1

这是我的代码,我的陈述是当 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 */
4

2 回答 2

0

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

我的建议是:

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

b) 看看 fpurge/fflush。我不确定使用 VC++ 可以为您提供什么,但 Google 会为您找到等价物。这些函数可用于在调用 scanf 之前丢弃待处理的输入。

高温高压

于 2013-03-16T10:56:19.670 回答
0

实际上,您的代码的行为符合预期。

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

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

Department期望 anint作为输入,当您输入其他内容时, d在这种情况下,scanfint在您循环时一直在寻找 an ,因此该行scanf("%d", &choice);也无法读取 anint并且choice没有重新分配新值,因此该switch语句始终看到最后一个的有效值choice。循环在下一次读取尝试时暂停。

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

这是验证整数输入的基本方法

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*){...}

于 2013-03-16T10:56:26.040 回答