【问题标题】:sscanf can't read last line of the text filesscanf 无法读取文本文件的最后一行
【发布时间】:2020-09-27 10:53:14
【问题描述】:
#include <stdio.h>

int main()
{

    FILE *fp;
    char buffer[1001];
    char name[15], surname[30];
    float mid1, mid2, final, avg;

    fp = fopen("grades.txt", "r");
    if (!fp)
    {
        printf("Could not open file. Program finished.");
        return 0;
    }

    fgets(buffer, 1000, fp);

    while (feof(fp) == 0)
    {
        sscanf(buffer, "%s%s%f%f%f", name, surname, &mid1, &mid2, &final);

        printf("%s %s %f %f %f\n", name, surname, mid1, mid2, final);

        fgets(buffer, 1000, fp);
    }

    fclose(fp);

    return 0;
}

这是我的文本文件,

Ali Veli 67 80 76
Ahmet Mehmet 45 64 63
Ayse Fatma 89 98 83

一切正常,但无法读取文本文件的最后一行 在输出“Ayse Fatma 89 98 83”中它无法打印。

【问题讨论】:

  • 看起来更像 C 而不是 C++。请选择一种语言。也值得一读:Why is while ( !feof (file) ) always wrong?
  • 谁教你使用while(feof(fp) == 0)
  • 虽然结构不好,但代码应该读取最后一行——如果数据文件末尾有换行符。如果缺少最后一个换行符,feof() 可能过早报告 EOF。建议的重组避免了一些可能的陷阱。您还可以打印您解析的行以查看在fgets() 调用之后是否有换行符:printf("Line: [[%s]]\n", buffer);。但是你应该在使用buffer 中的值之前检查fgets() 的结果,因此重组后的版本更好(没有重复),你可以将printf() 放在sscanf() 之前。
  • @BatuhanGunes 很高兴发布source 的弱代码。在其他代码示例中考虑这一点。

标签: c io scanf


【解决方案1】:

您可以轻松地使用fgets 返回的值作为while 循环的条件:

while(fgets(buffer, sizeof(buffer), fp))
{
    if(sscanf(buffer, "%14s%29s%f%f%f", name, surname, &mid1, &mid2, &final) == 5)
        printf("%s %s %f %f %f\n",name,surname,mid1,mid2,final);
}

当没有更多行可以从文件中读取时,循环将停止。

另外,一个好的做法是始终检查*scanf return。

还建议将"%s" 说明符的大小限制为它们的缓冲区,这将避免缓冲区溢出,在这种情况下"%14s""%29s" 分别为15 char 和30 char 缓冲区,size - 1 与保留的需要有关空终止符的空格。

您还应该按照@pzaenger's comment 中的链接了解while(feof(fp) == 0) 的使用。

【讨论】:

    猜你喜欢
    • 2012-07-22
    • 1970-01-01
    • 2010-10-15
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多