为什么这段代码没有指定访问数组的哪个元素?

时间:2014-01-29 15:48:05

标签: c arrays string

#include <stdio.h>
#include <stdlib.h>
FILE *fptr;

main()
{
    char fileLine[100];
    fptr = fopen("C:\\Users\\user\\Desktop\\Summary.h", "r");

    if (fptr != 0){
        while (!feof(fptr)){
            fgets(fileLine, 100, fptr); // << not specified like fileLine[1] ?
            if (!feof(fptr)){
                puts(fileLine); // The same thing ? 
            }
        }
    }
    else
    {
       printf("\nErorr opening file.\n");
    }

     fclose(fptr);

     return 0;
}

这里非常痛苦,为什么没有指定数组元素,以及数组如何保持数组?

2 个答案:

答案 0 :(得分:1)

char fileLine[100];

这不是一个行数组,而是一个字符数组。一个char表示一个字符(或更准确地说是一个字节)。声明char fileLine[100]使其成为一个包含100个字符的数组。 C没有字符串和字符数组的不同类型:字符串(例如行的内容)只是一个字符数组,在最后一个字符后面有一个空字节。

每次循环运行时,fileLine都包含fgets读取的行。该字符串由puts打印出来。每次调用fgets都会覆盖以前存储在字符串中的行。

请注意,由于fgets会保留终止每一行的换行符,并且puts在打印字符串后添加换行符,因此您将获得双倍行距输出。如果一行长度超过99个字符(严格来说,长度超过99个字节),则每个99个字符的块后都会有一个换行符。

如果你想存储所有的行,你需要一个字符串数组,即一组字符数组。

char fileLines[42][100];
int i = 0;
while (!feof(fptr)) {
    fgets(fileLines[i], 100, fptr);
    ++i;
}
/* i-1 lines have been read, from fileLines[0] to fileLines[i-2] */

你使用feof的方式非常尴尬。 feof告诉您最后一次读取操作是否到达文件末尾,而不是下次尝试读取是否到达文件末尾。例如,这里,在读完最后一行之后,feof()为假(因为程序还不知道这是最后一行,它必须尝试读取更多行);然后fgets再次运行,并返回NULL,因为它无法读取任何内容。尽管如此,i仍在增加;之后feof()返回false,终止循环。因此,i最终为一加上读取的行数。

虽然你可以通过递减i来解决这个问题,但即使在现实生活中的程序实际工作的方式 - 也更有意义 - 就是测试fgets的结果。您知道您已到达文件的末尾,因为fgets无法读取一行。

char fileLines[42][100];
int i = 0;
while (fgets(fileLines[i], 100, fptr))
    ++i;
}
/* i lines have been read, from fileLines[0] to fileLines[i-1] */

(这是一个玩具示例,现实生活中的代码需要动态内存管理和长行错误检查,行数过多,读取错误。)

答案 1 :(得分:0)

fileLine的字符数组被视为字符串。