C项目scanf()

这是我的代码,我的陈述是当while循环开始运行时显示选项并在第一次迭代时扫描选择但在第二次迭代中没有再次分配选择并且记住先前的选择。 问题是什么 ? (我正在使用VS2012)

while (!done){ int choice; printf("\n------- STUDENT INFORMATION SYSTEM MAIN MENU --------\n"); printf("1-Load students from the database\n"); printf("2-Print existing students on the screen\n"); printf("3-Add a new student\n"); printf("4-Delete an existing student\n"); printf("5-Find an existing student\n"); printf("6-Quit\n"); printf("====> Choice? "); scanf("%d", &choice); switch(choice){ case 1: LoadStudentsFromDatabase(); printf("Students loaded from database successfully\n"); break; case 2: PrintExistingStudentsOnTheScreen(); break; case 3: printf("\nFirstName: "); scanf("%s", s.firstName); printf("LastName: "); scanf("%s", s.lastName); printf("ID: "); scanf("%d", &s.id); printf("Gpa: "); scanf("%f", &s.gpa); printf("Department: "); scanf("%d", &s.department); AddStudent(&s); printf("1 student added\n"); break; case 4: printf("\nID? "); scanf("%d", &id); if (DeleteStudent(id)){ printf("Student deleted successfully\n"); } else { printf("Failed to delete the student. Does not exist?\n"); } /* end-else */ break; case 5: printf("\nID? "); scanf("%d", &id); ps = FindStudent(id); if (ps == NULL){ printf("Student not found\n"); } else { char *depts[] = {"CS", "EE", "IE", "CE", "ME"}; printf("+--------------------+--------------------+------+------+------+\n"); printf("| FirstName | LastName | ID | GPA | Dept |\n"); printf("+--------------------+--------------------+------+------+------+\n"); printf("|%20s|%20s|%6d|%6.2f|%6s|\n", ps->firstName, ps->lastName, ps->id, ps->gpa, depts[ps->department]); printf("+--------------------+--------------------+------+------+------+\n"); } //end-else break; case 6: done = 1; break; default: printf("!!!!!!!!!! Invalid choice. Try again :-))\n"); break; } /* end-switch */ } /* end-while */ 

可能发生的是当你第二次调用scanf时出现错误。 可能是因为非数字输入正在等待在stdin上读取。 也许你最后一次在代码正文中没有完全阅读所有输入? scanf因为您的转换格式%d而尝试读取一个数字而只读取一个数字,所以如果要读取的下一个数据不是数字,则它会失败,它会返回错误并保持choice不变。 您不检查此错误,因此假设choice包含新输入的值,实际上它只包含在调用scanf之前包含的内容。 scanf也可能因为更多错误而失败,但我怀疑在这里并非如此。

我的建议是:

a)检查scanf的返回值。 它应该在你的情况下返回1。 如果没有,则出现错误。 你可以挽救或再次出示菜单。

b)看看fpurge / fflush。 我不确定使用VC ++可以使用什么,但谷歌会找到你的等价物。 在调用scanf之前,这些函数可用于丢弃挂起的输入。

HTH

实际上你的代码表现得像预期的那样。

可以使用以下输入重现该行为

 FirstName: f LastName: l ID: 1 Gpa: 2 Department: d 

当你输入其他内容时, Department需要一个int作为输入,在这种情况下,当你循环时, scanf一直在寻找一个int ,所以行scanf("%d", &choice); 也无法读取int并且choice不会重新分配新值,因此switch语句始终会看到最后一个有效值供choice 。 循环在下一次读取尝试时暂停。

要解决您的问题,您需要validation输入并仅在您期望的输入有效时转到下一步。 您可以通过检查scanf的返回值来执行此操作,这是根据转换模式成功解析的项目数,在您的情况下,您只想读取one项目。

以下是validation整数输入的基本方法

 int read_integer(char* what) { int i = 0; printf("%s: ", what); int r = scanf("%d", &i); while(r == 0) { while('\n' != getchar()) // consume the rest of input until a LF comes (enter pressed) ; printf("Bad input for %s, try again (r=%d)\n", what, r); printf("%s: ", what); r = scanf("%d", &i); } return i; } 

在这里你怎么读Department

 int department = read_integer("Department"); 

你也可以为float写一个类似的函数 – > float read_float(char*){...}