有什么方法可以用小端程序读取大端数据吗?

时间:2010-01-07 18:02:49

标签: c++ endianness

外部组为我提供了在Big Endian机器上编写的文件,它们还为文件格式提供了C ++解析器。

我只能在一个小端机器上运行解析器 - 有没有办法在每次读取后使用解析器读取文件而不添加swapbytes()调用?

8 个答案:

答案 0 :(得分:13)

早在铁器时代早期,古人在试图将原始PDP-11小型机与其他原始计算机联网时遇到了这个问题。 PDP-11是第一台小端计算机,而当时大多数其他计算机都是大端计算机。

为了解决这个问题,他们一劳永逸地开发了网络字节顺序概念(总是big-Endia),以及相应的网络字节顺序宏ntohs(),ntohl(),htons()和htonl() 。用这些宏编写的代码将始终“得到正确答案”。

让您的外部供应商倾向于在他们的代码中使用宏,并且他们提供给您的文件将始终是big-Endian,即使他们切换到little-Endian机器。重写他们为您提供的解析器以使用宏,即使您切换到big-Endian机器,也始终能够读取其文件。

这个特定问题浪费了大量的程序员时间。有几天我认为可以为悬挂PDP-11设计师提出一个很好的论据。

答案 1 :(得分:2)

一般来说,没有“简单”的解决方案。您将不得不修改解析器以交换从文件读取的每个整数的字节。

答案 2 :(得分:2)

这取决于您对数据的处理方式。如果要打印数据,则需要在所有数字上交换字节。如果您正在查看文件中的一个或多个值,则字节交换比较值可能会更快。

一般来说,格雷格是正确的,你必须以艰难的方式去做。

答案 3 :(得分:2)

最好的方法是只定义文件格式的endianess,而不是说它依赖于机器。 无论运行什么CPU,编写器都必须以正确的顺序写入字节,读者必须这样做。

答案 4 :(得分:2)

尝试说服解析器团队包含以下代码:

int getInt(char* bytes, int num)
{
    int ret;
    assert(num == 4);
    ret = bytes[0] << 24;
    ret |= bytes[1] << 16;
    ret |= bytes[2] << 8;
    ret |= bytes[3];
    return ret;
}

它可能比一般int i = *(reinterpret_cast<*int>(&myCharArray));更耗时,但总是会在大端和小端系统上获得字节顺序。

答案 5 :(得分:0)

如果你不想修改它们的解析器,你可以编写一个包装解析器并反转字节的解析器。

注意要读入的数据类型.4字节intfloat需要字节序校正。一个4字节的ASCII字符串不会。

答案 6 :(得分:0)

一般来说,没有。

如果读/写调用不是类型感知的(例如,fread和fwrite不是),那么他们就无法区分编写endian敏感数据和endian不敏感数据。

根据解析器的结构方式,您可以避免一些痛苦,如果他们使用的I / O函数知道正在读/写的类型,那么您可以修改这些例程,应用正确的字节序转换。

如果你必须修改所有的读/写调用,那么创建这样的例程将是一个明智的做法。

答案 7 :(得分:0)

你的问题以某种方式包含答案:不!

  

我只能在一个小端机器上运行解析器 - 有没有办法在每次读取后使用解析器读取文件而不添加swapbytes()调用?

如果您在小端机器上阅读(并且想要解释)大端数据,那么必须以某种方式转换数据。您可以在每次读取后或读取整个文件后执行此操作(如果读取的数据不包含有关如何读取更多数据的任何信息) - 但无法省略转换。