C - fgets 在非空文件上返回 null



我正在尝试从文件中读取成对的非特定数量的整数。我还想跳过以#开头的行。我的问题是没有打印任何东西。当我尝试打印 fgets 返回的值时,它打印了 null。我真的很感激一点帮助,因为我对 C 不是很有经验,如果您不关注 feof,我将不胜感激,因为我已经阅读了为什么 feof 不好。

该文件如下所示:

#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 memoryn");
abort();
}

FILE* fd=fopen("File.txt","r");
if(fd==NULL){
printf("Error opening filen");
abort();
}
char buff[200];
int counter=0;
if(fopen==NULL){
printf("Error opening filen");
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("%dt%dn",array[counter].start,array[counter].end);
counter++;
}

fclose(fd);
free(array);
return 0;
}

首先,回答问题的标题:fgets()在文件末尾返回NULL,而不是在文件为空时返回。

无论如何,您在while循环中的测试是不正确的:

  • 只有当您已经尝试读取并且已经到达文件末尾且读取失败时,feof()才会给出真实的结果。read试图给你尽可能多的字节......或者根本没有,如果文件结束,则完全没有,获得文件结束条件的唯一方法是在您无法读取某些内容之后。最好检查fgets()结果,因为它返回NULL现在无法读取任何内容。(而不是在最后一次阅读中(所以

    while(fgets(buff, sizeof buff, fd) != NULL)
    

    或者只是

    while(fgets(buff, sizeof buff, fd))
    

    会好得多。 另外,请参阅我如何使用sizeof运算符来使用所用缓冲区的大小,而不是在两个位置重复(并且容易出错(实际字节数。 如果您决定更改缓冲区的大小,则还需要更改要在fgets()调用中读取的实际字节数,从而使忘记其中一个缓冲区的可能性成为遇到麻烦的机会。

  • 您命令仅在!feof()counter == 6保持循环(首先,这将使控件在计数器等于 6 时进入循环,无论您是否已达到 EOF,这都不是正确的(认为只有当两个条件都为 false 时才退出循环(这意味着feof()返回 true并且也返回counter != 6(, 你最好写:

    while(fgets(buff, sizeof buff, fd) && counter < max_number_of_iterations)
    
  • 测试内容

    if(strcmp(buff[0],"#"))
    

    也是不正确的,因为buff[0]是一个字符(实际上,它是缓冲区中读取的第一个字符,"#"是字符串文字(不是字符(可能您至少从编译器那里得到了警告,您没有说任何单词。 您最好测试两个字符的相等性,例如

    if (buff[0] == '#')  /* this time '#' is a character literal, not a string literal */
    
  • 在行中

    if (fopen == NULL)
    

    fopen本身就是一个指向库函数的指针,fopen(3)它不是你想要的(fopen总是!= NULL(,但是

    if (fd == NULL){
    

    (你之前做过,所以你最好消除这个代码(

  • 你定义一个char c;,然后将其初始化为buff的第一个字符,然后你根本不使用它。 这对你的代码没有影响,但它的风格很糟糕,将来会让维护者感到困惑。

  • 在行sscanf(&buff, "%d %d", ....中,您不需要传递&buff,而buff已经是一个字符指针。 最好将其传递buff.n 但是,您需要将指针传递给您正在读取的变量,因此您需要将其更正为:

    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 memoryn");
abort();  /* have you tried exit(EXIT_FAILURE); ?? */
}
FILE* fd=fopen("File.txt","r");
if(fd==NULL){
printf("Error opening filen");
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("%dt%dn", array[counter].start, array[counter].end);
counter++;
}
fclose(fd);
free(array);
return 0;
}

运行代码显示:

$ pru
1233    14432
4943928 944949
11233   345432

使用您发布的File.txt

最后,提示一下:

尽管你只想知道循环下降的原因,而不是为什么feof()在这里没有用(以及许多其他你只是不要求和代码中错误的东西(,但如果确实是这种情况,你最好发布一个示例,仅显示页面建议的失败行为如何创建一个最小值, 您应该阅读的完整且可验证的示例,我建议您这样做。

您不应该在while条件下检查feof()。请参阅为什么"while ( !feof (file(("总是错误的?。

循环应为:

while (fcounter < 5 && fgets(buff, 200, fd))

相关内容

  • 没有找到相关文章

最新更新