1

これが私のコードです。私のステートメントは、 while ループが show options の実行を開始し、最初の反復で選択をスキャンするが、2 番目の反復では選択が再度割り当てられず、前の選択が記憶されるということです。何が問題ですか ?(私は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 を 2 回目に呼び出すと、エラーが発生します。おそらく、数字以外の入力が標準入力で読み取られるのを待っているためです。前回、コードの本体ですべての入力を完全に読み取らなかった可能性がありますか? scanf は、変換形式のために数字と数字のみを読み取ろうとする%dため、次に読み取られるものが数字ではない場合、エラーが返され、choiceそのまま残ります。このエラーをチェックしないため、実際には scanf が呼び出される前に含まれていたものだけが含まれているにもかかわらず、choice に新しく入力された値が含まれていると想定します。scanf もエラーのような理由で失敗する可能性がありますが、ここではそうではないと思います。

私の提案は次のとおりです。

a) scanf の戻り値を確認します。あなたの場合は1を返すはずです。そうでない場合は、エラーが発生しています。救済するか、メニューをもう一度提示することができます。

b) fpurge/fflush を見てください。VC++ を使用して何が利用できるかはわかりませんが、Google は同等のものを見つけます。これらの関数は、scanf を呼び出す前に保留中の入力を破棄するために使用できます。

HTH

于 2013-03-16T10:56:19.670 に答える
0

実際、あなたのコードは期待どおりに動作しています。

動作は次の入力で再現できます

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

Departmentint他の何かを入力すると、入力として が 期待されます。dこの場合、scanfintはループ中に を探し続けます。そのため、その行は anのscanf("%d", &choice);読み取りに失敗し、新しい値が再割り当てされないため、ステートメントは常に最後の値を参照します。の有効な値。ループは次の読み取り試行で一時停止します。intchoiceswitchchoice

問題を解決するには、入力を検証し、期待する入力が有効な場合にのみ次のステップに進む必要があります。これを行うには、 scanf witchの戻り値が、変換パターンに従って正常に解析されたアイテムの数であることを確認します。この場合、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 に答える