windows下C中数据的字节表示。大端和小端
Byte presentation of data in C under windows. Big-endian & little endian
我有一些C代码,"fread"读了一些,但结果不是我所期望的。这是我的代码:
void main()
{
unsigned int *data =(unsigned int*)malloc(4);
static unsigned int ImageData[256][256];
char *filename= "C:\Users\Frank\Documents\Visual Studio 2012\Projects\UI\UI\bin\Debug\bin\result.txt";
FILE *pfile=fopen(filename,"rb");
for (int i = 0; i < 256; i++)
for (int j = 0; j < 256; j++)
{
fread(data, 4, 1, pfile);
ImageData[i][j] =(*data);
}
fclose(pfile);
printf("\nsize=%d",sizeof(unsigned int));
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
{
printf("\npixel[%d,%d]=%d",i,j,ImageData[i][j]);
}
}
我期望的十六进制是:
38 FC 0D 13 38 A7 D4 92 38 1F 32 B3 38 blabla...
两大问题:
始终检查相关系统调用的结果,如果您依赖它们的结果,通常就是这种情况。
FILE *pfile=fopen(filename,"rb");
应该是
FILE *pfile=fopen(filename,"rb");
if (NULL == pfile)
{
fprintf(stderr, "%s failed to open.\n", filename);
}
打印 unsigned int
时使用 %u
转换说明符。
所以这个
printf("\npixel[%d,%d]=%d", i, j,ImageData[i][j]);
应该是
printf("\npixel[%d,%d]=%u", i, j, ImageData[i][j]);
一些小问题:
C 标准将 main()
定义为 return int
.
所以这个
void main()
应该是
int main()
甚至更好
int main(void)
不需要在C中强制转换malloc/calloc/realloc
的结果,也不推荐以任何方式。
另外 malloc()
可能会失败。
所以通过
测试它的结果
data = malloc(4);
if (NULL == data)
{
/* Log error and probably exit ... */
}
fread()
也可能失败。
if (1 != fread(..., 4, 1, pfile))
{
/* read less then expected */
}
测量内存和索引数组的首选数据类型是 size_t
而不是 int
。在这种情况下不需要负值。
一些最后的提示:
如果您知道需要读取 32 位值(4 字节),请确保正确定义变量。
#include <inttypes.h> /* for u/int32_t */
uint32_t ImageData[256][256];
无需动态分配临时读取缓冲区
只需定义
uint32_t data;
并像这样使用它
if (1 != fread(&data, 4, 1, pfile))
{
...
ImageData[i][j] = data;
或者直接读入数组
if (1 != fread(&ImageData[i][j], 4, 1, pfile))
{
...
反正就是大小端问题。已解决。
ImageData[i][j] =_byteswap_ulong(ImageData[i][j]);
谢谢大家。
我有一些C代码,"fread"读了一些,但结果不是我所期望的。这是我的代码:
void main()
{
unsigned int *data =(unsigned int*)malloc(4);
static unsigned int ImageData[256][256];
char *filename= "C:\Users\Frank\Documents\Visual Studio 2012\Projects\UI\UI\bin\Debug\bin\result.txt";
FILE *pfile=fopen(filename,"rb");
for (int i = 0; i < 256; i++)
for (int j = 0; j < 256; j++)
{
fread(data, 4, 1, pfile);
ImageData[i][j] =(*data);
}
fclose(pfile);
printf("\nsize=%d",sizeof(unsigned int));
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
{
printf("\npixel[%d,%d]=%d",i,j,ImageData[i][j]);
}
}
我期望的十六进制是:
38 FC 0D 13 38 A7 D4 92 38 1F 32 B3 38 blabla...
两大问题:
始终检查相关系统调用的结果,如果您依赖它们的结果,通常就是这种情况。
FILE *pfile=fopen(filename,"rb");
应该是
FILE *pfile=fopen(filename,"rb"); if (NULL == pfile) { fprintf(stderr, "%s failed to open.\n", filename); }
打印
unsigned int
时使用%u
转换说明符。所以这个
printf("\npixel[%d,%d]=%d", i, j,ImageData[i][j]);
应该是
printf("\npixel[%d,%d]=%u", i, j, ImageData[i][j]);
一些小问题:
C 标准将
main()
定义为 returnint
.所以这个
void main()
应该是
int main()
甚至更好
int main(void)
不需要在C中强制转换
malloc/calloc/realloc
的结果,也不推荐以任何方式。另外
malloc()
可能会失败。所以通过
测试它的结果data = malloc(4); if (NULL == data) { /* Log error and probably exit ... */ }
fread()
也可能失败。if (1 != fread(..., 4, 1, pfile)) { /* read less then expected */ }
测量内存和索引数组的首选数据类型是
size_t
而不是int
。在这种情况下不需要负值。
一些最后的提示:
如果您知道需要读取 32 位值(4 字节),请确保正确定义变量。
#include <inttypes.h> /* for u/int32_t */ uint32_t ImageData[256][256];
无需动态分配临时读取缓冲区
只需定义
uint32_t data;
并像这样使用它
if (1 != fread(&data, 4, 1, pfile)) { ... ImageData[i][j] = data;
或者直接读入数组
if (1 != fread(&ImageData[i][j], 4, 1, pfile)) { ...
反正就是大小端问题。已解决。
ImageData[i][j] =_byteswap_ulong(ImageData[i][j]);
谢谢大家。