0

当我使用此代码时

FILE *f = fopen(file, "rb");
const char *d;
if (f!=NULL) {
    static char c[100000];
    fread(c, sizeof(char), 10000000, f);
    d = c;
    fclose(f);
    return d;
}
else{
    /*
     char *ff = f;
     perror(ff);
     */
    d = "Error";
    fclose(f);
    return d;
}

从包含这样文本的文件中读取

This
Is a test

它读起来很好。但是,如果我打开另一个包含此文本的文件

Test

它会读到类似

Test Is a test

为什么文件关闭时将两者合二为一?我现在放了这个,但我仍然得到相同的结果

if (f!=NULL) {
fread(c, sizeof(c), len, f);
d = c;
fclose(f);
c[99999] = '\0';
return d;
}
4

3 回答 3

4

fread()不会 NUL 终止它读取的缓冲区。如果第二次读取比第一次短,则未覆盖的第一次读取的其余部分将保留在那里。无论如何,您的程序在很多地方都调用了未定义的行为,这甚至都不好笑。

例如,这个:

static char c[100000];
fread(c, sizeof(char), 10000000, f);

很可能是一个错字 - 您允许fread()读取比缓冲区大小多 100 倍的数据。这就是为什么你应该总是(我的意思是,ALWAYS)使用sizeof()运算符和数组元素的大小而不是它的类型。此外,sizeof(char)始终为 1,不要拼写冗余数据:

fread(c, sizeof(c), 1, f);
于 2013-03-18T22:01:22.620 回答
4

看起来你的数组中还有上次读取的字符。您应该在返回之前 null 终止字符串,fread()不会为您执行此操作。

您还有其他一些问题,例如字符限制fread()大于缓冲区大小。

除非您真的需要 c,否则您应该考虑使用 c++ 甚至其他具有更复杂的文件和文本处理库的语言,它会让您的生活更轻松。

于 2013-03-18T22:01:34.613 回答
2

您正在将数据读入静态缓冲区,完成后不会终止字符串。因为c是静态的,所以初始化为零。fread()您使用来自调用的数据部分覆盖它。

因此,您应该使用 from 的返回值fread()并将其设置c[len]'\0'.

于 2013-03-18T22:02:49.717 回答