1. ホーム
  2. c

[解決済み] fgets()が関数内で動作しない [重複] [重複

2022-02-15 01:35:54

質問内容

私は、fgets()を使って、出発と到着のための空港コードとして3チャールの長さの文字列をスキャンするプログラムを書いています。このステートメントをそのメソッドの外側(mainの中)に書くとうまく動作しますが、内側では入力を待たず、変数は空白のままです。

void newFlight ()
    {
        printf("\n");
        printf("============= CREATE A NEW FLIGHT ============= \n");
        printf("Type 0 at any point to exit to main menu. \n");
        printf("\n");

        printf("EnterFlight ID (0 to cancel) : ");
        scanf("%d", &flyList[curFly].flightID);

        char codeA [4];
        printf ("Enter Destination (Airport Code): ");
        fgets(codeA, 3, stdin);
        strcpy(codeA, flyList[curFly].arrive);
        printf("%s   %s \n", codeA, flyList[curFly].arrive);  //TEST

        printf("Enter Place Of Departure: ");
        char codeD[4];
        scanf("%s", codeD);
        strcpy(codeD, flyList[curFly].depart);
        printf("%s   %s \n", codeD, flyList[curFly].depart);  //TEST

        printf("Enter Date Of Departure (DD MM YYYY): ");
        scanf("%hd %hd %hd", &flyList[curFly].timeOfDep.day, &flyList[curFly].timeOfDep.month, &flyList[curFly].timeOfDep.year);

        printf("Enter Time Of Departure (HH MM)in 24Hr Format: ");
        scanf("%hd %hd", &flyList[curFly].timeOfDep.hour, &flyList[curFly].timeOfDep.minute);       

        curFly++;
    }

解決方法は?

ミキシング fgets()scanf() が問題になります。

fgets() を消費します。 入る ( \n ).
scanf("%d", ... が見えます。 \n を停止させます。 %d を変換して \n に戻す stdin に対して IO操作 - それは偶然にもOPの fgets() という短い文字列を速やかに返します。

を確認する必要があります。 scanf() で幅を指定した場合は "%s のようにするのがよいでしょう。 "%3s .

手っ取り早い解決策は scanf()

 //  scanf("%d", &flyList[curFly].flightID);
if (1 != scanf("%d", &flyList[curFly].flightID)) handle_error();
 ...
char codeA [4];
// fgets(codeA, 3, stdin);
if (1 != scanf("%3s", codeA) handle_error();
...
// Likely backwards
// strcpy(codeA, flyList[curFly].arrive);
strcpy(flyList[curFly].arrive, codeA);
...
char codeD[4];
// scanf("%3s", codeD);
if (1 != scanf("%3s", codeD)) handle_error();
...
// scanf("%hd %hd %hd", &flyList[curFly].timeOfDep.day, &flyList ...
if (3 != scanf("%hd %hd %hd", &flyList[curFly].timeOfDep.day, &flyList[curFly].timeOfDep.month, &flyList[curFly].timeOfDep.year)) handle_error();
...
// scanf("%hd %hd", &flyList[curFly].timeOfDep.hour, &flyList ...
if (2 != scanf("%hd %hd", &flyList[curFly].timeOfDep.hour, &flyList[curFly].timeOfDep.minute)) handle_error();

より良い解決策は fgets()/sscanf()

 //  scanf("%d", &flyList[curFly].flightID);
char buf[100];
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOForIOError();
if (1 != sscanf(buf, "%d", &flyList[curFly].flightID)) handle_parse_error();
... 
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOForIOError();
if (1 != sscanf(buf, "%3s", flyList[curFly].arrive) handle_parse_error();
...
etc.

ちなみに。 scanf() フォーマット "%hd %hd""%hd%hd" は同じことをします。