C fgets在非空文件上返回null
我试图从文件中读取非特定数量的成对整数。我还想跳过以#开头的行。我的问题是什么也没印出来。当我尝试打印fgets返回的值时,它打印为null。我真的很感激你能给我一点帮助,因为我对C不是很有经验,如果你不关注feof,我会非常感激,因为我已经读过为什么feof是坏的 该文件如下所示:C fgets在非空文件上返回null,c,file-io,null,fgets,C,File Io,Null,Fgets,我试图从文件中读取非特定数量的成对整数。我还想跳过以#开头的行。我的问题是什么也没印出来。当我尝试打印fgets返回的值时,它打印为null。我真的很感激你能给我一点帮助,因为我对C不是很有经验,如果你不关注feof,我会非常感激,因为我已经读过为什么feof是坏的 该文件如下所示: #This must #be #skipped 1233 14432 4943928 944949 11233 345432 代码是: #include<stdio.h> #include<
#This must
#be
#skipped
1233 14432
4943928 944949
11233 345432
代码是:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
int start;
int end;
}path;
int main()
{
path* array;
array=malloc(5*sizeof(path));
if(array==NULL){
printf("Error allocating memory\n");
abort();
}
FILE* fd=fopen("File.txt","r");
if(fd==NULL){
printf("Error opening file\n");
abort();
}
char buff[200];
int counter=0;
if(fopen==NULL){
printf("Error opening file\n");
abort();
}
char c;
while(!feof(fd)||counter==6){
fgets(buff,200,fd);
c=buff[0];
if(strcmp(buff[0],"#")){
continue;
}
sscanf(&buff,"%d %d",array[counter].start,array[counter].end);
printf("%d\t%d\n",array[counter].start,array[counter].end);
counter++;
}
fclose(fd);
free(array);
return 0;
}
#包括
#包括
#包括
类型定义结构{
int启动;
内端;
}路径;
int main()
{
路径*数组;
数组=malloc(5*sizeof(path));
if(数组==NULL){
printf(“分配内存时出错”);
中止();
}
FILE*fd=fopen(“FILE.txt”、“r”);
如果(fd==NULL){
printf(“打开文件时出错”);
中止();
}
字符buff[200];
int计数器=0;
如果(fopen==NULL){
printf(“打开文件时出错”);
中止();
}
字符c;
而(!feof(fd)|计数器==6){
fgets(buff,200,fd);
c=增益[0];
if(strcmp(buff[0],“#”)){
继续;
}
sscanf(&buff,“%d%d”,数组[计数器]。开始,数组[计数器]。结束);
printf(“%d\t%d\n”,数组[counter]。开始,数组[counter]。结束);
计数器++;
}
fclose(fd);
自由(数组);
返回0;
}
您不应在while
条件下选中feof()
。看
循环应为:
while (fcounter < 5 && fgets(buff, 200, fd))
while(fcounter<5&&fgets(buff,200,fd))
首先,回答问题的标题:fgets()
在文件末尾返回NULL
,而不是在文件为空时返回
无论如何,您在while
循环中的测试不正确:
仅当您已尝试读取并且已到达文件结尾且读取不成功时,才会给出真实结果。当feof()
尝试为您提供尽可能多的字节时。。。如果文件结束,则获取文件结束条件的唯一方法是在读取某些内容失败后。最好检查read
result,因为它在现在无法读取任何内容时返回fgets()
。(并非最后一读)如此 或者只是NULL
那就更好了。另外,请参见如何使用while(fgets(buff, sizeof buff, fd))
运算符来使用已用缓冲区的大小,而不是重复(并且容易出错)两个位置的实际字节数。如果您决定更改缓冲区的大小,还需要更改sizeof
调用中要读取的实际字节数,这样就有可能忘记其中一个字节,从而导致出现问题fgets()
- 只有在
或当期间,您才可以命令留在循环中!feof()
时(首先,这将使控件在计数器等于6时进入循环,尽管您是否已达到EOF,这不可能是正确的)认为只有在两个条件都为false时才能退出循环(这意味着计数器==6
返回true并且也返回计数器!=6),您最好编写:feof()
也是不正确的,因为while(fgets(buff, sizeof buff, fd) && counter < max_number_of_iterations)
是一个字符(实际上,它是缓冲区中读取的第一个字符,buff[0]
是一个字符串文字(不是字符),您可能至少从编译器得到了一个警告,从中可以说没有单词。您最好测试两个字符是否相等,如中所示“#”
if (buff[0] == '#') /* this time '#' is a character literal, not a string literal */
- 排队
if (fopen == NULL)
本身就是指向库函数的指针fopen
,这不是您想要的(fopen(3)
总是fopen
),但是 (您以前是这样做的,因此最好删除所有此代码)!=NULL
- 您定义了一个
,然后将其初始化为char c;
的第一个字符,然后您就根本不使用它了。这对您的代码没有影响,但它的样式不好,并且会让将来的维护人员感到困惑buff
- 在
您不需要传递sscanf(&buff),“%d%d”行中,…
,而&buff
已经是一个字符指针。最好传递buff
。n但是,您需要传递指向正在读取的变量的指针,因此需要将其更正为:buff
不这样做将导致未定义的行为,这将很难实现,因为使用未初始化的变量(以及更多指向变量的指针)可能会使代码一开始工作,但在生产一段时间后失败……这是一个非常严重的错误sscanf(buff, "%d%d", &array[counter].start, &array[counter].end);
文件.txt
最后,一个提示:
尽管您只想知道循环下降的原因,而不想知道为什么
feof()
在这里没有用处(以及许多其他您没有要求的东西,这些东西在代码中是错误的),如果确实是这样,您最好发布一个示例,该示例只显示您应该阅读的页面所建议的失败行为,我建议您这样做。如果(fopen==NULL){则此语句,如果(strcmp(buff[0],“#”)则此语句){没有意义。counter==6
应该是counter<5
你在哪里检查fgets()的值?
?Azzarian“如果你不关注feof,我将非常感激,因为我已经阅读了为什么feof不好”,这与(!feof(fd)相反…<代码>是问题的一个重要部分。请考虑修复并查看编译器警告。
if (fopen == NULL)
if (fd == NULL){
sscanf(buff, "%d%d", &array[counter].start, &array[counter].end);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N (5) /* I have defined this constant so you can
* change its value without having to go all
* the code for occurrences of it and
* changing those */
typedef struct{
int start;
int end;
} path;
int main()
{
path* array = malloc(N*sizeof(path)); /* better declare and init */
if(array==NULL){
printf("Error allocating memory\n");
abort(); /* have you tried exit(EXIT_FAILURE); ?? */
}
FILE* fd=fopen("File.txt","r");
if(fd==NULL){
printf("Error opening file\n");
abort();
}
char buff[200];
int counter=0;
while(fgets(buff, sizeof buff, fd) && counter < N){
if(buff[0] == '#'){
continue;
}
sscanf(buff, "%d %d", &array[counter].start, &array[counter].end);
printf("%d\t%d\n", array[counter].start, array[counter].end);
counter++;
}
fclose(fd);
free(array);
return 0;
}
$ pru
1233 14432
4943928 944949
11233 345432