而依赖于scanf结果的循环过早结束

时间:2014-01-12 13:15:31

标签: c while-loop scanf

我正在用C编写一个简单的程序来计算成绩和成绩平均值。我通过“< xyz.txt”从命令行提供文本文件,并通过“> xyz_output.txt”命令输出到另一个文本。输入文件中有超过100行数据,但由于某种原因,程序一直在输入的第6行退出循环...我已经多次检查输入格式,我似乎无法弄清楚为什么它过早地退出了。这是代码:

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

int main()
{
    char pp[4];
    char school[3];
    int class;
    int student;
    int a;
    int b;
    int c;
    int d;
    int e;
    int f;
    int g;
    int h;
    int i;
    int j;
    int k;
    int l;
    int m;
    int n;
    int o;
    int p;
    int q;
    int r;
    float average;
    int runtotal;
    int grouptotal = 0;
    float groupaverage;
    int counter = 0;
    while (scanf("%3s%2s%2i%2i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", pp, school, &class, &student, &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o, &p, &q, &r) == 22)
    {
        runtotal = (a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r);
        average = (float)runtotal / 18;
        grouptotal = grouptotal + runtotal;
        counter++;
        printf ("%i.\n", counter);
        printf ("%s%s-%i-%i -- %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i %1i\n", pp, school, class, student, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r);
        printf ("Total score: %i\n", runtotal);
        printf ("Average: %f\n", average);
        printf ("Running Total: %i\n\n", grouptotal);
    }
    groupaverage = (float)grouptotal / counter;
    printf ("Calculations complete.\nThe total score for this group was %i.\nThe average score for this group was %f.\n", grouptotal, groupaverage);
    return 0;
}

以下是实际输入.txt文件的前10行。

preKO6101 0 0 1 1 1 1 1 0 1 0 1 0 0 1 1 0 2 0
preHI6114 1 0 0 1 0 1 1 1 1 0 0 0 0 1 1 1 2 1
preHI5116 0 0 0 1 0 0 1 1 1 0 0 0 0 2 0 0 1 0
preHI6103 0 0 0 1 0 0 1 1 1 0 0 0 0 1 1 0 0 1
preHI5132 0 0 0 1 1 0 1 1 1 0 0 0 0 1 0 0 0 0
preHI5109 1 0 0 1 1 0 0 1 0 0 0 0 1 1 1 2 2 1
preHI6113 2 1 1 1 1 0 1 0 0 0 1 0 1 1 1 0 0 1
preSA5116 0 1 0 1 1 2 1 2 0 0 0 0 2 1 2 0 2 2
preHI6109 0 0 0 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1
preHI5107 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 0

它似乎成为'preHI5109',但随后退出。我有一种感觉,它与我如何使用scanf有关,但我不确定我做错了什么。关于如何解决这个问题的任何建议?

1 个答案:

答案 0 :(得分:0)

用于读取数据文件的方法对错误对齐,解析和I / O问题非常敏感。建议更强大的IO和解析,因为数据文件中肯定存在一些小错误。使用fgets()来控制读取面向行的数据。

char buf[100];
while (fgets(buf, sizeof buf, stdin) != NULL) {
  int count = sscanf(buf, "%3s%2s%2i%2i %i %i %i %i /* ... */ %i %i", 
    pp, school, &class, &student, &a, &b, &c, /* ... */  &q, &r);
  if (count != 22) {
    printf("Error %d (TBD relevant text)\n", count);
    break;
  }
  /* continue with normal processing */
}

其他改进
  int a[18]代替int a; int b; ...
  使用循环然后扫描,求和,打印18个元素   使用"%i"而不是"%1i"1最小宽度,为什么要这样呢?

注意:如果输入文件是由教授提供的,那么故意不好的东西就不会让我感到惊讶。经验教训:除非经过严格审查,否则不要相信数据输入。用户输入是邪恶的。