分配存储和二进制fwrite短裤在c
我想分配一个短裤块,将其写入一个文件, 然后再读回。但是写入 文件的数据与出现的数据不匹配。我已经将问题 隔离为以下代码。任何想法我做错了什么?分配存储和二进制fwrite短裤在c
#define CHUNK_SIZE 1000
void xwriteStructuresToFile(FILE *file, void * structureData)
{
assert((fwrite(structureData, sizeof(short), CHUNK_SIZE, file)) == CHUNK_SIZE);
}
void wwbuildPtxFiles(void)
{
FILE *file = fopen("s:\\tv\\run32\\junky.bin", WRITE_BINARY);
int count = 10;
short *ptx = (short *) calloc(CHUNK_SIZE * count, sizeof(short));
memset(ptx, '3', sizeof(short) * CHUNK_SIZE * count);
for (int dayIndex = 0; dayIndex < count; ++dayIndex)
xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);
free(ptx);
fclose(file);
file = fopen("s:\\tv\\run32\\junky.bin", READ_BINARY);
int xcount = CHUNK_SIZE * count * sizeof(short);
for (int i = 0; i < xcount; ++i)
{
char x;
if ((x = getc(file)) != '3')
assert(false);
}
}
有几件事情:
你打开文件的方式,我不知道你的常量,但他们应该读
"wb"
写一个二进制文件,"rb"
阅读。
永远不要在声明中放置语句,当程序在释放模式下编译时会断开声明。相反,检查返回值并断言该
例如,
bool ok =fwrite(structureData, sizeof(short), CHUNK_SIZE, file)) == CHUNK_SIZE;
assert(ok);
虽然你不应该在这个断言,而是应该先打印出正确的错误信息。 断言是用于编程错误,而不是运行时错误。
上述行包含了一些问题:
的
calloc
在C.short *ptx = calloc...
绝不会把返回值应该足够了, 如果你得到一个警告,#include <stdlib.h>
你应该使用形式
calloc(count, CHUNK_SIZE * sizeof(short));
它否则看起来有点不清楚。 词(calloc需要的数量,大小作为参数)
for (int dayIndex = 0; dayIndex < count; ++dayIndex)
xwriteStructuresToFile(file,
(void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);
不知道你是在那里做什么,与
fwrite(ptx, CHUNK_SIZE * sizeof(short), count, fp);
那应该写整个数组。
在您的来电xwriteStructuresToFile
,您可以使用:
&ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]
ptx
是一个短指针,这意味着数组计算将自动放大到一个短的大小。
通过在上述表达式中明确地做到这一点,您的行为远远超出了数组的末尾。您需要替换该行的东西,如:
xwriteStructuresToFile(file, &ptx[CHUNK_SIZE * dayIndex]);
因为ptx
是short *
指针,你不应该由sizeof(short)
乘以当你索引它。该指数是在short
秒为单位了,所以你想要的:从数组索引
xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * dayIndex ]);
删除的sizeof(短)。 C会为你做这个计算
你正在写'数据'超出数组的末尾!自动
xwriteStructuresToFile(file, &ptx[CHUNK_SIZE * dayIndex]);
C编译器刻度由sizeof(short)
:
xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);
您应该使用。如果您有整数数组,则不要编写array[i * sizeof(int)]
来访问数组的成员;如果您有整数数组,则不写array[i * sizeof(int)]
以访问数组的成员;同样,在这里你不需要通过sizeof(short)
来缩放索引。的确,至关重要的是,你不这样做,因为你写了两次(假设sizeof(short) == 2
)远远超过你的预期。
您也不应该在必须执行的函数调用周围使用assert()
。您可以在单独的语句中使用assert()
,该语句可以在不影响其功能的情况下从程序中省略。 Steve Maguire在'Writing Solid Code'中对此进行了一定的讨论,这篇文章有点过时了,但至少在这一点上听起来很有道理。
不要对操作代码执行'assert()'即使用'-DNDEBUG'编译,发生'fwrite()'也是至关重要的。 – 2012-02-14 05:32:22