1
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>

int main()
{
    std::ifstream file("data.bin", std::ios::binary );

    if( file.fail() )
    {
        std::cout << "File does not exist or could not open file";

        return 0;
    }

    std::vector<short> buffer;

    std::copy( 
            std::istreambuf_iterator<char>( file ),
            std::istreambuf_iterator<char>(),
            std::back_inserter( buffer )
            );

   return 0;
}

这只会给我 char 值的范围(-128、128)。

我认为 usingistreambuf_iterator<short>会给我我想要的东西,但它会引发“无效转换”错误。

我该怎么做才能读取short范围内的二进制值?

4

2 回答 2

2

该类std::istreambuf_iterator<cT>遍历从 astd::basic_istream<cT, std::char_traits<cT>>或实际上是它的 中提取的字符std::basic_streambuf<cT, std::char_traits<cT>>。也就是说,给定特定的流类型,对于std::istreambuf_iterator<cT>. 另请注意,IOStream 层并非旨在对二进制文件进行操作,尽管该std::ios_base::binary操作被传递到流缓冲区。

如果您想提取shorts (或任何其他类型,而不是流的字符类型),您需要自己创建一个合适的迭代器,该迭代器将文件写入时选择的二进制格式考虑在内。这个迭代器可以构建std::istreambuf_iterator<char>或直接访问std::streambuf.

于 2012-12-02T01:32:39.770 回答
1

这是我推荐的 Spirit 方法:

#include <fstream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

int main()
{
    std::ifstream file("data.bin", std::ios::binary);
    if(!file)
        std::cout << "File does not exist or could not open file";
    boost::spirit::istream_iterator f(file), l;

    std::vector<int16_t> buffer;
    bool ok = qi::parse(f, l, *qi::word, buffer);
}

当然,还有qi::dword, qi::qword, big-endian/little-endian 变体等:


你可以看看 wchar_t

#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
    std::wifstream file("data.bin", std::ios::binary );
    if( file.fail() )
    {
        std::cout << "File does not exist or could not open file";
        return 0;
    }
    std::vector<wchar_t> buffer;
    std::copy( 
            std::istreambuf_iterator<wchar_t>( file ),
            std::istreambuf_iterator<wchar_t>(),
            std::back_inserter( buffer )
            );
}

我不太确定 wchar_t 的实际大小是否是实现定义的。

于 2012-12-02T01:32:30.300 回答