首页 > 解决方案 > 将数据从文件读入程序的错误输出

问题描述

我一直在研究一个程序,将文件中的数据读取到程序中并打印出来:

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char *p;
    int e;
    float f;
    static char a[50];
    FILE *fp;
    fp = fopen("new_input.txt", "r");
    if (fp == NULL)
        exit(0);
    while (1)
    {
        p = fgets(a, 50, fp);
        if (p == NULL)
            break;
        printf("%s", a);
        printf("\n");
        fscanf(fp, "%d", &e);
        printf("%d", e);
        printf("\n");
        fscanf(fp, "%f", &f);
        printf("%f", f);
        printf("\n");
    }
    fclose(fp);
    return 0;
}

文件 new_input.txt 的内容是:

Girik
12   
19.98   
Nikhil
13
90.89

但是在 OnlineGdb 上运行时,我得到以下输出:

Girik 
     
12 
19.980000   
      
     
12  
19.980000 
khil         
13          
90.889999 

有人可以用我的代码解释问题吗?

我担心输出和打印值 12 和 19.99 两次的不完整名称“Nikhil”。

代码链接: https ://onlinegdb.com/r1ufoP8-d

标签: cfiledebuggingio

解决方案


问题的出现是因为 lastfscanf不解析\n,所以当循环重新开始时,fgets将解析并打印它,自然 nextfscanf无法解析字符串 ( "Nikhil",它没有被解析),因为它期望一个int,它从下坡在那里,由于未解析值,因此打印的是上一个周期的旧ef

如果你改变你的最后一个fscanf,它会解析\n一切正常:

现场演示

while (1)
{
    p = fgets(a, 50, fp);
    if (p == NULL)
        break;
    printf("%s", a);
    fscanf(fp, "%d", &e);
    printf("%d", e);
    printf("\n");
    fscanf(fp, "%f\n", &f); //<--here
    printf("%.2f", f);//.2f specifier so it prints only 2 decimal places
    printf("\n");
}

指针也是不必要的,您可以将fgets其自身用作条件,

while (fgets(a, sizeof a, fp)) //will read until the end of the file
{
    printf("%s", a);
    //... same code
}

无论如何,这是一个您可以使用的版本,它将为您呈现预期的结果和输出,而且我认为更好:

现场演示

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int e;
    float f;
    static char a[50];
    FILE *fp;
    fp = fopen("new_input.txt", "r");
    if (fp == NULL){
        return EXIT_FAILURE;
    }
    // will parse until \n or 49 characters max (given the container size)
    while (fscanf(fp, " %49[^\n]", a) > 0)
    //                 ^ space - will discard any blank characters         
    {
        printf("%s\n", a);
        if(fscanf(fp, "%d", &e) > 0){
            printf("%d\n", e);
        }
        if(fscanf(fp, "%f", &f) > 0){
            printf("%.2f\n", f);
        }
    }
    fclose(fp);
    return EXIT_SUCCESS;
}

我还添加了fscanf退货检查,这始终是一个很好的做法。

甚至:

//...
while (fscanf(fp, " %49[^\n]%d%f", a, &e, &f) == 3)
{
    printf("%s\n%d\n%.2f\n", a, e, f);
}
//...

但是,我相信最好的解决方案是用or /解析所有内容fgets并转换值,这是一个更强大的选择。试试看。sscanfstrtolstrtof


推荐阅读