我有三个数组,所有这些数组一开始都基本相同。它们都以 50 个条目开头,并且都是整数数组。然而,其中一个立即填充大值,而其他 2 个以通常的 0,0,0 开始,...是什么让这个数组从其他数组中脱颖而出?按照提供最小示例的建议,我在下面发布了一个。它可能可以进一步减少,但我留下了所有的打印语句只是为了说明这是一个 Heisenbug 的情况。确实,如果我删除更多行,问题可能不会出现,我想确保它出现以便可以消除它。
int main() {
int assignments;
int i; /*for loop index for both loops*/
int days_late[50], scores[50], weights[50];
scanf(" %d",&assignments);
/*assigns assignment data from input to days_late, scores, weights*/
for(i=0; i<assignments; i++){
int index;
printf(" Index scanned: %d",scanf(" %d",&index));
printf(" Index is: %d",index);
printf("\nScore just added is %d",scores[index]);
printf("\nWeight just added is %d",weights[index]);
printf("\nLateness just added is %d",days_late[index]);
printf("\nIndex is %d",index);
printf(" Variables scanned: %d",scanf(" %d%d%d",&scores[index],&weights[index],&days_late[index]));
printf("\nScore just added is %d",scores[index]);
printf("\nWeight just added is %d",weights[index]);
printf("\nLateness just added is %d",days_late[index]);
}
/*anything past this point is not neccessary, the error has already occurred*/
}
Run Code Online (Sandbox Code Playgroud)
输出:
Index scanned: 1 Index is: 2
Score just added is -1793035504
Weight just added is 0
Lateness just added is 0
Index is 2 Variables scanned: 0
Score just added is -1793035504
Weight just added is 0
Lateness just added is 0 Index scanned: 0 Index is: 2
Score just added is -1793035504
Weight just added is 0
Lateness just added is 0
Index is 2 Variables scanned: 0
Score just added is -1793035504
Weight just added is 0
Lateness just added is 0
Run Code Online (Sandbox Code Playgroud)
说真的,分数和体重/迟到有什么区别?只有其中一个似乎从一开始就搞砸了。
编辑:我嵌套了 scanf 和 printf 来检查成功扫描了多少变量,返回的数字正是我所期望的。所以没有新的信息。
这是从中读取输入的文件:
10 0 Y
2
2, 80, 40, 0
1, 100, 60, 0
Run Code Online (Sandbox Code Playgroud)
前两行被正确处理,涉及它们的变量无论如何都不在上面的代码块中。所以文件也可能是
2, 80, 40, 0
1, 100, 60, 0
Run Code Online (Sandbox Code Playgroud)
问题是你在逻辑上试图把“马车放在马前”。程序流程是顺序的。在尝试输出存储的值之前,您需要读取并存储您正在寻找的值。在您的代码中,您尝试在获得输入以填充值(或在声明期间初始化值)之前输出未初始化(例如不确定)的值。如上所述,这会导致Undefined Behavior:
C11 标准 - 6.7.9 初始化(p10) “如果没有明确初始化具有自动存储持续时间的对象,则其值是不确定的。” 和C11 标准 - J.2 未定义行为“具有自动存储持续时间的对象的值在不确定时使用(6.2.4、6.7.9、6.8)。”
为了让“马回到购物车之前”,您需要考虑在您的代码中需要按顺序发生什么,以确保您的变量在尝试输出值之前正确填充了输入。此外,如果您从答案中没有得到任何其他信息,请了解您无法正确使用任何输入函数,除非您检查返回以确定输入是成功还是失败。
看你的代码,它似乎要提示用户的数量assignments为数组元素进入,然后循环回吐输入score, weight和days_late,然后显示输入的内容以确认输入。
使问题复杂化的是,您尝试让用户index在将存储值的数组中输入 此外,该index值必须在每个数组中的元素范围内,例如0 <= index < 50. index在使用它之前验证范围内的范围取决于您——或者您将通过尝试写入和读取数组边界之外的值来再次调用未定义行为。
为了消除整个index问题,因为您正在循环,只需读取与循环变量对应的赋值的值。(例如,而不是scores[index]简单地scores[i]在您的循环中使用)循环控制被提示和填充的索引。
将它们放在一起并验证每个输入(如果输入无效则简单地退出),您可以执行以下操作:
#include <stdio.h>
int main (void) {
int assignments,
i, /* for loop index for both loops */
days_late[50] = {0}, /* initialize arrays all zero */
scores[50] = {0},
weights[50] = {0};
fputs ("\nEnter No. assignments: ", stdout); /* prompt for no. assignments */
/* VALIDATE EVERY INPUT - both the conversion and that the value is within range */
if (scanf("%d", &assignments) != 1 || assignments < 0 || assignments > 49) {
fputs ("error: invalid integer input or input out of range.\n", stderr);
return 1;
}
/* loop assignments times */
for (i = 0; i < assignments; i++) {
/* display assignment no. prompt for score, weight, days_late */
printf ("\nassignment[%2d]\nenter score, weight, days_late: ", i + 1);
if (scanf ("%d%d%d", /* read and VALIDATE each value */
&scores[i], &weights[i], &days_late[i]) != 3) {
fputs ("error: invalid integer input - scores, weights, days_late.\n",
stderr);
return 1;
}
/* output values read */
printf ("\nScore just added is %d\n"
"Weight just added is %d\n"
"Lateness just added is %d\n",
scores[i], weights[i], days_late[i]);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意,您可以更优雅地处理错误检查,以便在创建(或EOF生成)有效条目之前重新提示用户,但在输入逻辑解决后由您决定。有关示例,请参阅C 中 isalpha 函数未返回正确值的答案— 将所有输入标记为 AZ 字符。
示例使用/输出
$ ./bin/scoreswtsdays_late
Enter No. assignments: 2
assignment[ 1]
enter score, weight, days_late: 88 1 0
Score just added is 88
Weight just added is 1
Lateness just added is 0
assignment[ 2]
enter score, weight, days_late: 91 1 2
Score just added is 91
Weight just added is 1
Lateness just added is 2
Run Code Online (Sandbox Code Playgroud)
这涵盖了我对您正在尝试的内容的理解。如果我读错了什么,请告诉我,我很乐意提供进一步的帮助。同样,如果您需要对上述任何内容进行进一步解释,请在下面发表评论。
发布输入文件格式后编辑
虽然我们仍然不清楚第一行的含义,但鉴于您的剩余描述,assignments从第 2 行开始阅读,然后循环assignments阅读index, scores, weights, days_late是相当简单的。
由于您正在阅读一行,因此您将需要使用面向行的输入函数,例如fgets()(或 POSIX getline())。注意面向行的函数'\n'在它们填充的缓冲区中读取并包含每一行的末尾(尽管这里用 解析sscanf,不需要特殊的调整)
要处理您的输入文件,只需读取前两行中的每一行即可获取读取文件其余部分所需的信息。不要忘记验证assignments从第 2 行读取的值是否在数组边界的范围内。
从第 3 行开始,只需读取该行,然后使用sscanf验证每行发生的预期转换次数来解析该行中的值。这些值很容易从带有格式字符串的行中解析出来 "%d, %d, %d, %d"
把这些碎片放在一起,你可以这样做:
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void) {
char buf[MAXC]; /* character array used as buffer for input */
int assignments,
i = 0, /* loop counter */
days_late[50] = {0}, /* initialize arrays all zero */
scores[50] = {0},
weights[50] = {0};
if (!fgets (buf, MAXC, stdin)) { /* read/validate line 1 */
fputs ("error: insufficient input - line 1\n", stderr);
return 1;
}
/* parsing the 3 values left to you until description given */
printf ("line 1: %s", buf); /* simply output line 1 */
if (!fgets (buf, MAXC, stdin)) { /* read/validate line 2 */
fputs ("error: insufficient input - line 1\n", stderr);
return 1;
}
/* parse assignments from buf, validate in range */
if (sscanf (buf, "%d", &assignments) != 1 || assignments < 0 || assignments > 49) {
fputs ("error: invalid assignments values line - 2\n", stderr);
return 1;
}
while (i < assignments && fgets (buf, MAXC, stdin)) {
int index, score, weight, dayslate; /* temporary value to read into */
/* parse values from line, VALIDATE 4 conversion took place */
if (sscanf (buf, "%d, %d, %d, %d", &index, &score, &weight, &dayslate) != 4 ||
index < 0 || index > 49) {
fputs ("error: invalid line format, lines 3+, or index out of range\n",
stderr);
return 1;
}
scores[index] = score; /* assign values to array[index] */
weights[index] = weight;
days_late[index] = dayslate;
/* output values read */
printf ("\nassignment[%2d]:\n"
" Score just added is : %d\n"
" Weight just added is : %d\n"
" Lateness just added is: %d\n",
index, scores[index], weights[index], days_late[index]);
i++; /* increment counter */
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
示例使用/输出
将输入文件放入 中dat/scoreswtsdays.txt,在将数据文件重定向为输入的同时运行程序将导致以下结果:
$ ./bin/scoreswtsdays_late_file < dat/scoreswtsdays.txt
line 1: 10 0 Y
assignment[ 2]:
Score just added is : 80
Weight just added is : 40
Lateness just added is: 0
assignment[ 1]:
Score just added is : 100
Weight just added is : 60
Lateness just added is: 0
Run Code Online (Sandbox Code Playgroud)
再看一遍,如果您还有其他问题,请告诉我。