fwrite一个整数取决于字节顺序,但有没有办法将一个整数0x00000004写入一个文件,这样它就可以始终作为0x00000004而不管它运行的机器。
一种想法是写第一位,然后是第二位,然后第三位总是以特定顺序写入,例如使用模数或位移来抓取每个十进制值。
不确定是否有办法强制fwrite以小端编写,而不进行一些复杂的检查以查看当前系统是否为大端,然后在写入之前反转这些位。
另一个想法是将它作为ascii存储在文件中,这不是一个大问题,它只是将4个字节转换为8(十六进制)。但我认为这只是一个懒惰的解决方案。
我想从可能不同的机器进行fwrite和fread,所以这两个操作都需要能够伪装和伪装相同的endianness,而且我不确定(在搜索这个站点之后)以便携式方式执行此操作(没有使用某些模糊的库,可能在某些机器上,也可能不在某些机器上。)
答案 0 :(得分:1)
我认为你不必担心比特级别的字节序,我认为它们总是一样的 how is data stored at bit level according to "Endianness"?
我可能会使用固定的endiannes来存储数据,并为fread和fwrite创建一些包装函数。
所以说你决定将所有内容存储在little endian中,包装器将检查机器的字节顺序并且:
编辑例如,你的fwrite可能看起来像这样(虽然没有经过测试,只是为了说明这个想法)。来自C program to check little vs. big endian的字节顺序检查:
size_t lendian_fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream)
{
if (size != 4)
{
/* Warn and exit */
}
int x = 1;
if ( *((char*)&x) == 1)
{
/* Little endian machine, use fwrite directly */
return fwrite(ptr, size, nmemb, stream);
}
else
{
/* Big endian machine, pre-process first */
unsigned char *buffer = (unsigned char*) ptr;
for (int i=0; i<nmemb; i++)
{
unsigned char a = buffer[4*i];
unsigned char b = buffer[4*i + 1];
buffer[4*i] = buffer[4*i + 3];
buffer[4*i + 1] = buffer[4*i + 2];
buffer[4*i + 2] = b;
buffer[4*i + 3] = a;
}
return fwrite(ptr, size, nmemb, stream);
}
}
答案 1 :(得分:0)
小即兴
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static size_t lendian_fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream)
{
int x = 1;
if ( *((char*)&x) == 1)
{
/* Little endian machine, use fwrite directly */
return fwrite(ptr, size, nmemb, stream);
}
else
{
if(size == sizeof(uint8_t)) //1 Byte
{
return fwrite(ptr, size, nmemb, stream);
}
else if(size == sizeof(uint16_t)) //2 Byte
{
/* Big endian machine, pre-process first */
unsigned char *buffer = malloc(size*nmemb);
unsigned char *input = (unsigned char*) ptr;
for (uint32_t i=0; i<nmemb; i++)
{
buffer[2*i] = input[2*i + 1];
buffer[2*i + 1] = input[2*i];
}
int ret =fwrite((void*)buffer, size, nmemb, stream);
free(buffer);
return ret;
}
else if(size == sizeof(uint32_t)) //4 Byte
{
/* Big endian machine, pre-process first */
unsigned char *buffer = malloc(size*nmemb);
unsigned char *input = (unsigned char*) ptr;
for (uint32_t i=0; i<nmemb; i++)
{
buffer[4*i ] = input[4*i + 3];
buffer[4*i + 1] = input[4*i + 2];
buffer[4*i + 2] = input[4*i + 1];
buffer[4*i + 3] = input[4*i ];
}
int ret =fwrite((void*)buffer, size, nmemb, stream);
free(buffer);
return ret;
}
else if(size == sizeof(uint64_t)) //8 Byte
{
/* Big endian machine, pre-process first */
unsigned char *buffer = malloc(size*nmemb);
unsigned char *input = (unsigned char*) ptr;
for (uint32_t i=0; i<nmemb; i++)
{
buffer[8*i ] = input[4*i + 7];
buffer[8*i + 1] = input[4*i + 6];
buffer[8*i + 2] = input[4*i + 5];
buffer[8*i + 3] = input[4*i + 4];
buffer[8*i + 4] = input[4*i + 3];
buffer[8*i + 5] = input[4*i + 2];
buffer[8*i + 6] = input[4*i + 1];
buffer[8*i + 7] = input[4*i ];
}
int ret =fwrite((void*)buffer, size, nmemb, stream);
free(buffer);
return ret;
}
else
{
printf("%s Function received invalid element size:%ld\n",__FUNCTION__,size);
return -1;
}
}
}
int main()
{
uint8_t buf1[8] = { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 };
uint16_t buf2[4] = { 0x1122,0x3344,0x5566,0x7788 };
uint32_t buf3[2] = { 0x11223344, 0x55667788 };
uint64_t buf4 = { 0x1122334455667788 };
FILE *ofp = NULL;
if((ofp=fopen("file.bin","wb"))==NULL)
{
printf("Cannot open output file!");
return -1;
}
lendian_fwrite(&buf1, sizeof(uint8_t),sizeof(buf1),ofp);
lendian_fwrite(&buf2, sizeof(uint16_t),sizeof(buf2)/sizeof(uint16_t),ofp);
lendian_fwrite(&buf3, sizeof(uint32_t),sizeof(buf3)/sizeof(uint32_t),ofp);
lendian_fwrite(&buf4, sizeof(uint64_t),sizeof(buf4)/sizeof(uint64_t),ofp);
fclose(ofp);
}