Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何写和写独立的整数,这样我可以在许多机器上写和写,并且总是有相同的结果_C_Fwrite_Endianness_Fread - Fatal编程技术网

C 如何写和写独立的整数,这样我可以在许多机器上写和写,并且总是有相同的结果

C 如何写和写独立的整数,这样我可以在许多机器上写和写,并且总是有相同的结果,c,fwrite,endianness,fread,C,Fwrite,Endianness,Fread,fwrite一个整数取决于endianness,但是有没有一种方法可以将整数0x00000004写入一个文件,这样无论它在哪台机器上运行,它都可以始终作为0x00000004写入 一种想法是总是按特定顺序写入第一位、第二位、第三位,例如使用模或位移位获取每个十进制值 不确定是否有办法强制fwrite以小尾端形式写入,而不必进行一些复杂的检查以查看当前系统是否为大尾端,然后在fwrite之前反转位 另一个想法是将其作为ascii码存储在文件中,这不是什么大问题,它只是将4个字节转换为8(十六进制

fwrite一个整数取决于endianness,但是有没有一种方法可以将整数0x00000004写入一个文件,这样无论它在哪台机器上运行,它都可以始终作为0x00000004写入

  • 一种想法是总是按特定顺序写入第一位、第二位、第三位,例如使用模或位移位获取每个十进制值

  • 不确定是否有办法强制fwrite以小尾端形式写入,而不必进行一些复杂的检查以查看当前系统是否为大尾端,然后在fwrite之前反转位

  • 另一个想法是将其作为ascii码存储在文件中,这不是什么大问题,它只是将4个字节转换为8(十六进制)。但我认为这只是一个懒惰的解决方案


我想从可能不同的机器上进行fwrite和fread,因此这两个操作都需要能够以相同的结尾进行fwrite和fread,我不确定(搜索此站点后)是否可以通过便携方式进行此操作(而不必使用某些机器上可能存在或不存在的模糊库).

我认为你不必担心位级的端点,我认为它们总是一样的

我可能会使用固定的endiannes来存储数据,并为fread和fwrite生成一些包装函数

因此,假设您决定将所有内容存储在little endian中,包装商将检查机器的endian度,并:

  • 如果机器是little endian,则直接使用fread和fwrite
  • 如果机器是big-endian,则相应地交换字节。显然,您将假定只使用int对齐的读/写(如果您混合了不同的长度类型,那么您的包装器将无法知道要交换哪些字节)
编辑例如,您的fwrite可能是这样的(虽然没有经过测试,只是为了说明想法)。端度检查来自:

size\u t lendian\u fwrite(const void*ptr、size\u t size、size\u t nmemb、,
文件*流)
{
如果(尺寸!=4)
{
/*警告并退出*/
}
int x=1;
如果(*(字符*)&x)==1)
{
/*小端机,直接使用fwrite*/
返回fwrite(ptr、大小、nmemb、流);
}
其他的
{
/*大端机,先预加工*/
无符号字符*缓冲区=(无符号字符*)ptr;

对于(int i=0;i我刚刚制作了这个简单的尾端交换fwrite。适用于任何尾端,在需要交换字节顺序时使用它。适用于每个元素大小,并且不更改原始数据:

size_t endian_swap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    unsigned char *buffer_src = (unsigned char*)ptr;
    unsigned char *buffer_dst = new unsigned char[size*nmemb];
    for (size_t i = 0; i < nmemb; i++)
    {
        for (size_t ix = 0; ix < size; ix++) {
            buffer_dst[size * i + (size - 1 - ix)] = buffer_src[size * i + ix];
        }
    }
    size_t result = fwrite(buffer_dst, size, nmemb, stream);
    delete buffer_dst;
    return result;
}
size\t endian\u swap\u fwrite(const void*ptr、size\t size、size\t nmemb、FILE*stream)
{
无符号字符*buffer_src=(无符号字符*)ptr;
unsigned char*buffer_dst=新的unsigned char[size*nmemb];
对于(大小i=0;i
at的各种方法,例如使用ntohl/htonl。据我所知,ntohl没有那么好的可移植性。是的,但它是POSIX规范的一部分:。如果你不想依赖它,那么你可以按照独立于网络的顺序写入字节,而不是位。字节中的位是否没有endianness?或者只有字节。比如,一个字节是8位ts,00000001,将该字节写入任何机器上的文件会使其始终保持不变还是…?如何在机器之间传输数据?对于联网,它应该“自动”处理,例如,请参阅。这似乎是最好的解决方案。但问题是,如果我有一个包含10字节的char*流,我从一个文件(如“1234567890”和我一次写入1个字节,endianness不重要,对吗?它总是以读取的方式写入,1234567890我认为您不必担心一次写入多少字节。假设您的文件是常规磁盘文件(文件可以是*nix系统上的所有类型的东西,比如带有有趣线条规则的串行端口等),而您的文件系统没有什么特殊的功能,您需要考虑的是数据在内存缓冲区中的顺序,以及它将如何写入文件(另一种方式是读取)。将其强制转换为什么或一次写入多少字节并不重要。字符数组不受endianness的影响(并且一次可以写入10个字符)
size_t endian_swap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    unsigned char *buffer_src = (unsigned char*)ptr;
    unsigned char *buffer_dst = new unsigned char[size*nmemb];
    for (size_t i = 0; i < nmemb; i++)
    {
        for (size_t ix = 0; ix < size; ix++) {
            buffer_dst[size * i + (size - 1 - ix)] = buffer_src[size * i + ix];
        }
    }
    size_t result = fwrite(buffer_dst, size, nmemb, stream);
    delete buffer_dst;
    return result;
}