【问题标题】:Strange input with fscanffscanf 的奇怪输入
【发布时间】:2012-04-29 13:18:52
【问题描述】:

我正在尝试使用 fscanf 读取文本文件。输入文件如下所示:

1
Test
0
32.1

除了作为随机值读取的第一个整数之外,其他所有内容都可以正常读取。

我的代码:

while((fgets(string,64,fp) != NULL)){
    fscanf(fp, "%i\n", &tid);
    fscanf(fp, "%s\n", name);
    fscanf(fp, "%d\n", &stat);
    fscanf(fp, "%f\n", &per);
    printf("%d %s %d %f", tid, name, stat, per);
    }

输出:

11281472 Test 0 32.0999982

有谁知道我做错了什么?

整个函数供参考:

Task *readData(Task *strt, char *fname){
    #ifdef DEBUG
        fprintf(stderr, "Entered Data import method\n");
    #endif
    char name[30];
    int tid, stat;
    float per;

    FILE *fp;
    fp= fopen(fname, "r");

    if(fgetc(fp) == EOF){
        printf("File is empty");
    }
    else{
    while(!feof(fp)){

        fscanf(fp, "%i\n", &tid);
        fscanf(fp, "%s\n", name);
        fscanf(fp, "%d\n", &stat);
        fscanf(fp, "%f\n", &per);
        printf("%d %s %d %f", tid, name, stat, per);
        strt = AddB(strt, tid, name, stat, per);
        }
    }
    return (strt);
}

【问题讨论】:

  • 第一个 fscanf 之前的 fgets,这会加载到 string 中吗?
  • 您使用while 循环,一切正常!
  • 应该有while循环,因为输入不限于一个块。

标签: c scanf


【解决方案1】:

fgets 读取(使用)输入文件中的第一个字符串,然后首先fscanf 尝试将“Test”解析为“%i”格式并失败。

您可以在 while 循环中使用 feof 作为条件,但是(感谢 John Bode)最好检查每个 fscanf 并使用标志或 break

每个fscanf 都会返回一个值。如1中所述:

返回值

成功完成后,这些函数应返回成功匹配和分配的输入项的数量;如果发生早期匹配失败,此数字可以为零。如果输入在第一次匹配失败或转换之前结束,则返回 EOF。如果发生读取错误,则设置流的错误指示符,返回 EOF,并设置 errno 以指示错误。

因此,您可能需要检查每个 fscanf 的返回值,以了解出现(读取)错误。

更新: 你永远不应该使用 fgets/fgetc 来检查某些东西(不用fseek 倒回或用ungetc 撤消),因为每个文件读取函数都会从文件中读取数据(文件中的当前位置将增加)。要检查错误,只需查看用于解析输入的常用 fscanf/其他函数的返回值。

【讨论】:

  • 我将循环条件更改为 !feof(fp) 但现在文件中的第一个 int 仍被读取为随机数。我已添加输出以供参考。
  • @Jonas 但是您现在使用fgetc 而不是fgets。为什么??
  • fgetc 只是检查文件是否为空。我对 C 比较陌生,所以我的代码预计会很脏。
  • 不! fgetc 不只是检查文件是否为空! “如果文件没有更多内容则返回 EOF”位只是一个副作用,而不是这个函数的主要目的。
  • 不,他应该使用feof作为他的循环条件,因为它不会返回true,直到他尝试之后读过去的 EOF,这意味着他的循环将经常执行一次。他应该针对fscanf 的结果进行测试。
【解决方案2】:

你没有检查每次调用是否失败,所以你不知道发生了什么。

(我对此进行了编辑以删除 %i 无效的断言,抱歉)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多