fgets读取的数量大于存储大小的fgets

时间:2018-04-18 01:25:22

标签: c fgets

我正在查看代码来学习东西,我看到了类似的东西:

void funRead(){
     char str[80];
     FILE *fi;
     fi = fopen("file","r");
     while(!feof(fi)){
        fgets(str, 200, fi);
        // do things
     }
     fclose(fi);
}

它有效! (这是一个非常大的代码)我不明白为什么它正在工作所以我试图重现它(只是这部分,几乎只是上面的代码)和我的程序崩溃(我' m在 Eclipse 上执行此操作。它只在我写

时才有效
fgets(str, 80, fi);

或其他数字< 80,否则它不会工作。

我错过了什么吗?

编辑:我正在讨论的程序部分的屏幕截图 https://gyazo.com/c8847ccc36bbbe7a406a3260db8dd358 第4行& 26

2 个答案:

答案 0 :(得分:3)

fgets(str, 200, fi);确实是错误的,因为它告诉fgets要读 实际上str可以存储最多79个字符(不是 包括'\0' - 终止字节),这就是"与fgets(str, 80, fi);一起工作" 1 的原因。

一般情况下,使用sizeof这样的 2 是个好主意:

char str[80];
fgets(str, sizeof str, fi);

使用sizeof,即使您后来决定更改,也会获得正确的尺寸 str的大小。

really wrong的一件事是:

while(!feof(fi))
{
    ...
}

代码应该做的是:

while(fgets(str, sizeof str, fi))
{
    // do things
}

这是阅读整个文件的正确方法。

<强> Fotenotes

1 我把作品放在引号中,因为代码检查何时停止 阅读不正确。但是fgets(str, 80, fi)是正确的电话。

2 请注意,sizeof仅在strsizeof时才会给出正确的尺寸 阵列。如果它是一个指针,你为它分配了内存,那么你就无法使用 size_t len = 80; char *str = malloc(len); if(str == NULL) { // error handling } fgets(str, len, fi); // <-- do not use sizeof here, but the variable ,例如:

{{1}}

答案 1 :(得分:2)

在您的代码中,您要定义一个大小为80个字符的字符数组

char str[80];


fgets(str, 200, fi);

以上声明表示正在读取字符数组“ str ”中文件“ fi ”中的 200 字符 80 即可。 您无法在大小为80的数组中复制200个字符。

使字符数组变大或从文件中一次读取80个或更少的字符。

编辑:程序崩溃的原因是它正在访问非法内存位置。这并不意味着如果索引一个大于数组大小的位置就必须崩溃,这只是意味着如果不允许它访问该内存位置它就会崩溃。 所以这就是原因,你提到的代码可能正在工作(纯粹是偶然),尽管那200个部分是错误的。如果它运行然后多次运行它可能会至少崩溃一次。