【问题标题】:C - How fgets works with mutiple callsC - fgets 如何处理多个调用
【发布时间】:2018-12-23 14:24:41
【问题描述】:

我有以下代码:

int i = 0;
char ar[500];

while(i < 20)
{
    printf("Type a line: ");
    fgets(ar, 500, stdin);
    fprintf(fp,"%s", ar);
    i++;
}

基本上,我试图打开一个文件,然后从用户那里获取 20 行输入并将其存储在一个数组中,然后将其打印到文件中。它工作正常,但我不明白 fgets 在 while 循环中是如何工作的。据我了解,当 i = 0 时,fgets 将第一行存储到 ar[500],fprintf 将其打印到文件中,当 i = 1 时,fgets 将第二行存储到 ar[500],但现在 ar[500]有 2 行,但是为什么 fprintf 只将第 2 行打印到文件中,而不是所有 2 行,等等当我递增 1 时。

【问题讨论】:

标签: c file fgets


【解决方案1】:

fgets 总是在 arr[0] 处开始填充数组。在每次迭代中,前一行都会被覆盖。 fgets 会在 arr 中为你添加空终止符,所以只有当前读取的行会输出到 fp 指向的 FILE 中。

【讨论】:

    【解决方案2】:

    char *fgets(char * restrict s, int n, FILE * restrict stream); 的描述是(C11 7.21.7p2)

    2 fgets 函数从stream 指向的流中读取最多比n 指定的字符数少一个到s 指向的数组中。在换行符(保留)之后或文件结尾之后不会读取其他字符。在读入数组的最后一个字符之后立即写入一个空字符。

    fgets 读取的第一个字符将始终存储在s[0] 等等,直到最多s[n - 1] 或遇到的第一个换行符(它是存储的最后一个字符)。读取最后一个字符之后的元素将被设置为'\0',因此终止字符串。

    即实际上,fgets 调用将覆盖数组中的第一个元素k + 1,其中k 是行的长度或n,以较小者为准,1 表示空终止。

    要存储 20 行,您需要一个数组数组:

    char ar[20][500];
    

    然后读入ar[i]

    【讨论】:

    • 当一个while循环时:while( fgets(ar, 500, fp) ) puts(ar);读取文件,每次 fgets 读取时,它都会返回下一行(就像第一次一样,fgets 读取第一行并将其打印到屏幕上,第二次返回第二行,将其打印到屏等)。你知道 fgets 是如何记住它离开的地方吗?
    • @ThuanNguyen fgets 没有,但FILEs 有一个固有的机制 - file position indicator 在文件被读取时向前移动。
    【解决方案3】:

    缓冲区ar 每次都会被覆盖。

    fgets 具有原型char *fgets(char *str, int n, FILE *stream)。它将从stream 中读取最多n-1 个字符并将它们写入str,然后添加'\0' 字符。

    【讨论】:

      【解决方案4】:

      关于:“但现在 ar[500] 有 2 行,”

      不,函数fgets() 不附加。

      相反,它会叠加。

      在发布的代码中,总是从ar[0]开始

      【讨论】:

        猜你喜欢
        • 2019-01-24
        • 2019-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-12
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        相关资源
        最近更新 更多