使用C程序读取输入的小错误

时间:2014-02-23 08:59:29

标签: c scanf

我以为我已经启动并运行了这个程序,但是在第二次查看输出文件时,我注意到计算中出现了一些“看似随机”的错误印记。在追踪所有错误的数字后,我发现了一个奇怪的错误模式,我无法解释或弄清楚,尽管我有一种感觉,它与存储在内存中的二进制代码有关。

程序应该采用一行一行的文本文件,每行遵循三个字母的格式('pre'或'pos')然后再写两个代表学校ID的字母,表示班级的两个数字(此组合有4种可能性,51,52,61或62),最后两位数字代表学生的ID。第一位构成数据条目的ID标记。标签之后是一行18个单位数整数,范围从0到2.这些是学生在测试中遇到的18个问题中的每个问题得到的分数。以下是单个数据条目的示例,正​​在处理的文本文件各有100行。 preIS6114 0 0 0 1 1 2 1 1 0 0 0 1 1 0 0 0 0

我遇到的问题是,当程序读取一行数据时,大部分时间读取它就好了,做了它应该做的事情,并继续前进。然而!如果ID标签的最后两位数字是08或09,程序认为学生的ID号是0,并且测试的第一个SCORE分别是8或9,这当然是不可能的,因为2是学生可以在问题上获得的最高分数。我看了,当然,在学生ID为08或09的每个实例中,都发生了这个错误。较低的ID(01到07)工作正常,ID高于09 ....所以为什么只有这两个数字?我发现这很不寻常......

这是我第二次使用这个程序,第一次,用户输入引起了各地的问题,所以有人建议先使用fgets,然后使用scanf来解析数据,我这样做了得到了程序的工作(或者我认为......直到第二次看输出数据我才注意到这个问题)

我和C一起工作,我不是程序员,我是英语教授,所以我显然不知道有关C的一切。鉴于此,请不要担心我的程序的其他问题(因为我知道有很多),除非你认为它会导致其他错误。代码非常冗长,所以我将删除所有简单的int变量声明,只是为了节省空间并专注于有问题的部分。

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;

//several lines skipped here...//


while (fgets(buf, sizeof buf, stdin) != NULL) {
  int count = sscanf(buf, "%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);
  if (count != 22) {
    printf("Error %d (TBD relevant text)\n", count);
    break;
  }
    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;
    xscore = (float)runtotal - trueavg;
    xscoresqr = (float)xscore * xscore;
    runxscore = (float)runxscore + xscoresqr;

//more happens inside this while loop here... I edited it out for this post//



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);
}
//the while loop ends here//

所以我认为问题在于在缓冲区中读取和存储数据......也许......

只是为了给出一个输入和输出正在做什么的好例子,这里有两个...... INPUT ...

preHI5214 1 0 0 1 0 2 2 2 1 0 0 0 2 2 2 1 2 2
preKO5211 0 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 0
preIS5109 0 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 1 0
preSA6211 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 1 2 1
preSA6209 0 0 0 1 0 0 1 1 2 0 0 0 1 1 0 0 0 0
preHI6205 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 2 1
preKO5212 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0
preSA6210 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0
preHI6208 0 1 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 1
preKO5209 0 0 0 1 1 0 1 1 0 0 0 0 1 1 0 0 0 0
preHI5211 0 0 0 1 1 0 1 2 1 0 0 1 1 1 1 1 0 0
preKO6217 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 0 0 0
preIS5108 0 0 0 1 1 0 1 1 0 0 0 0 1 1 1 0 1 1

和输出...... ...

88.
preHI-52-14 -- 1 0 0 1 0 2 2 2 1 0 0 0 2 2 2 1 2 2
Total score: 20
Average: 1.111111
Running Total: 932

89.
preKO-52-11 -- 0 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 0 0
Total score: 7
Average: 0.388889
Running Total: 939

90.
preIS-51-0 -- 9 0 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 1
Total score: 15
Average: 0.833333
Running Total: 954

91.
preSA-62-11 -- 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 1 2 1
Total score: 11
Average: 0.611111
Running Total: 965

92.
preSA-62-0 -- 9 0 0 0 1 0 0 1 1 2 0 0 0 1 1 0 0 0
Total score: 16
Average: 0.888889
Running Total: 981

93.
preHI-62-5 -- 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 2 1
Total score: 10
Average: 0.555556
Running Total: 991

94.
preKO-52-12 -- 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0
Total score: 5
Average: 0.277778
Running Total: 996

95.
preSA-62-10 -- 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 0 0
Total score: 5
Average: 0.277778
Running Total: 1001

96.
preHI-62-0 -- 8 0 1 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0
Total score: 13
Average: 0.722222
Running Total: 1014

97.
preKO-52-0 -- 9 0 0 0 1 1 0 1 1 0 0 0 0 1 1 0 0 0
Total score: 15
Average: 0.833333
Running Total: 1029

98.
preHI-52-11 -- 0 0 0 1 1 0 1 2 1 0 0 1 1 1 1 1 0 0
Total score: 11
Average: 0.611111
Running Total: 1040

99.
preKO-62-17 -- 0 0 0 1 0 0 1 0 0 0 0 0 1 1 1 0 0 0
Total score: 5
Average: 0.277778
Running Total: 1045

100.
preIS-51-0 -- 8 0 0 0 1 1 0 1 1 0 0 0 0 1 1 1 0 1
Total score: 16
Average: 0.888889
Running Total: 1061

如果您查看以下五个条目的输入和输出数据,您会清楚地看到我的意思...... preIS5109,preSA6209,preHI6208,preKO5209和preIS5108

那我怎么能纠正这个?

1 个答案:

答案 0 :(得分:6)

使用%2d代替%2i

当与%i格式说明符匹配时,任何以0开头的数字都被解释为octal。这对于仅包含0到7的数字的数字无关紧要,但包含8或9的数字无效,导致%2i输入匹配失败。