使用fscanf输入奇怪的内容

时间:2012-04-29 13:18:52

标签: c scanf

我正在尝试使用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);
}

2 个答案:

答案 0 :(得分:2)

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

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

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

  

返回值

     

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

因此,您可能需要检查每个fscanf的返回值,以确定某些内容(读取)错误。

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

答案 1 :(得分:0)

你没有检查每次通话的失败,所以你不知道发生了什么。

(我编辑了这个以删除%i无效的说法,抱歉)