我正在尝试分配单个短裤块,将其写入文件, 然后读回去。 但是写入的数据 文件与发布的内容不匹配。 我已经隔离了问题 到以下代码段。知道我做错了什么吗?
#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);
}
}
从数组索引中删除 sizeof(short(。C 将为您进行此计算
几件事:
您打开文件的方式,我不确定您的常量,但它们应该读取
"wb"
写入二进制文件,"rb"
读取。
切勿将语句放在断言中,当程序在发布模式下编译时,断言将被删除。相反,检查返回值并断言
例如
bool ok =fwrite(structureData, sizeof(short), CHUNK_SIZE, file)) == CHUNK_SIZE;
assert(ok);
虽然你不应该断言这一点,但你应该打印出一个正确的错误消息。断言用于编程错误,而不是运行时错误。
short *ptx = (short *) calloc(CHUNK_SIZE * count, sizeof(short ) );
上面的行包含许多问题:
从不强制转换 C 中的
calloc
返回值。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]);
您正在将"数据"写入数组末尾之外!
xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * sizeof(short) * dayIndex ]);
您应该使用:
xwriteStructuresToFile(file, &ptx[CHUNK_SIZE * dayIndex]);
C 编译器会自动按sizeof(short)
进行缩放。 如果你有一个整数数组,你不需要写array[i * sizeof(int)]
来访问数组的第 i个成员;同样,在这里您不需要按 sizeof(short)
缩放索引。 事实上,你不这样做是至关重要的,因为你在内存中写了两次(假设sizeof(short) == 2
(和你预期的那样远。
您也不应该在必须执行的函数调用周围使用assert()
。 您可以在单独的语句中使用assert()
,该程序可以从程序中省略,而不会影响其功能。 史蒂夫·马奎尔(Steve Maguire(在《编写固体代码》(Writing Solid Code(一书中对此进行了较长时间的讨论,这在某些地方有点过时,但至少在这一点上是合理的。
因为ptx
是一个short *
指针,所以在索引它时不应该乘以sizeof(short)
。 索引的单位已经是 short
s,因此您需要:
xwriteStructuresToFile(file, (void *) &ptx[ CHUNK_SIZE * dayIndex ]);