将二进制文件中的小端读入 C++ 中的整数

问题描述

我正在解析一个 wav 文件,并按照给定的系数减慢或加快它的速度。所以我想从wave文件头中读取采样率和字节率,并根据因子进行修改。问题是它们是小端的。

在 C 中,我可以做到这一点

inline void endian_swap(unsigned int& x)
    {
        x = (x>>24) | 
            ((x<<8) & 0x00FF0000) |
            ((x>>8) & 0x0000FF00) |
            (x<<24);
    } 

然后

unsigned int num;
while ( fread(&num,1,4,fp) != 0) 
endian_swap(num); 

但是我如何在 C++ 中做同样的事情? 我试过了

    int length = 4; 
    my_input_file.read(&num,length);

但它不起作用,因为编译器期望第一个参数中有一个字符指针。我在代码中到处都使用文件流,这就是为什么我不能只使用文件指针并以 C 方式执行。知道我该怎么做吗?

另外,我可以使用 sscanf 将二进制文件中的 little-endian 格式的数据直接读取为整数吗?

解决方法

在 C 中,我可以做到这一点

您的方法存在的问题是:

  1. 仅当字节为 8 位时才有效。 C(或 C++)不保证这一点。
  2. 仅当 usigned int 有 4 个字节时才有效。 C(或 C++)标准不保证这一点。
  3. 如果 CPU 本身是大端的,则应该只对小端输入进行交换。 C(或 C++)标准不保证这一点。 请注意,x86 是小端。
  4. C 没有引用。

但是我如何在 C++ 中做同样的事情?

除了上述问题外,endian_swap 恰好是有效的 C++。

在 C++ 中,您可以使用例如这个来将二进制文件读入内存:

std::ifstream is(filename,std::ios::in | std::ios::binary);
std::istreambuf_iterator<char> begin = is;
std::istreambuf_iterator<char> end = {};
std::vector<unsigned char> data(begin,end);