#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;
}
这里的巨大痛苦,为什么未指定数组元素,以及数组如何保持线路?
char fileLine[100];
这不是一系列线条,而是字符数组。一个char
代表一个字符(或更准确地说是一个字节)。声明char fileLine[100]
使其成为100个字符的数组。C对于字符串和字符数组没有不同的类型:字符串(例如行的内容)只是一个字符数组,在最后一个字符之后具有null字节。
在每次通过循环运行时,fileLine
包含fgets
读取的行。该字符串由puts
打印出来。每个呼叫fgets
覆盖以前存储在字符串中的行。
请注意,由于fgets
保留了终止每行的NewLine字符,并且puts
在打印字符串后添加了一个Newline,因此您将获得双间隔输出。如果一条线长度超过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,该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] */
(这是一个玩具示例,现实生活中的代码需要动态内存管理和错误检查长行,太多行和读取错误。)
fileLine
字符的数组被视为字符串。