2

これがコードの書き方です。

int main()
{   
    char enteredName[30];
    char stringNum[4];
    char continueLetter = 0;
    int continueProgram = 0;
    int enteredAge;
    int i;

    do
    {
    memset(enteredName,'\0', 30);
    printf("Please enter a name: ");
    fgets(enteredName, 29, stdin);

    printf("\n\nNow please enter your age: ");
    fgets(stringNum, 3, stdin );

    for(i = 0; i < 30; i++)
    {
        if (enteredName[i] == '\n')
        {
            enteredName[i] = '\0';
            break;
        }
    }

    for(i = 0; i < 4; i++)
    {
        if (stringNum[i] == '\n')
        {
            stringNum[i] = '\0';
            break;
        }
    }

    enteredAge = atol(stringNum);
} while();

もう一度ループを実行すると、char 配列に新しい名前を入力できず、次のプロンプト (年齢) に進むだけです。この問題がリンクされたリストに関係していない限り、問題は別のものにあるようです。エラーを見つけるのを手伝ってもらえますか? ありがとう!

4

4 に答える 4

1

問題は、入力バッファをフラッシュしていないことです。これが、fgets()年齢を尋ねる 2 番目のプロンプトに直接移動する理由です。これはよくある問題です。fflush(stdin);//my compiler supports it後に追加するだけfgets();です。 :

編集:に関する情報を提供する非常に有用な投稿fflush()が 1 つあります。説明されているように、fflush は基本的に出力ストリームに呼び出されることを意図しています。一部のコンパイラはフラッシュのサポートを提供しますstdinが、これは未定義の動作と見なされます。プログラム、使用すると驚くほどsizeof機能し、有効であることがわかりました。そのため、プログラムをより適切に変更しました。の使用についてsizeofは、こちらの回答の 1 つでも説明されています。

#include<stdio.h>
#include<stdlib.h>
int main()
{   
    char enteredName[30];
    char stringNum[4];
    int continueProgram=0;
    int i;

   while(continueProgram<3)
      {
        setbuf(stdout,NULL);
    printf("Please enter a name: ");
    fgets(enteredName, sizeof enteredName, stdin);
    printf("\n\nNow please enter your age: ");
    fgets(stringNum,sizeof stringNum, stdin );

   for(i = 0; i < 30; i++)
    {
        if (enteredName[i] == '\n')
        {
            enteredName[i] = '\0';
            break;
        }
    }

    for(i = 0; i < 4; i++)
    {
        if (stringNum[i] == '\n')
        {
            stringNum[i] = '\0';
            break;
        }
    }

    //enteredAge = atol(stringNum);
    continueProgram++;
    }
    return 0;
}
于 2013-06-21T06:42:27.303 に答える
1

2 桁の年齢を入力すると、2番目のfgets呼び出しで文字 (具体的には改行) が読み取られるのを待機します。stdin

配列のサイズに合わせて長さパラメーターを増やします。

fgets(stringNum, 4, stdin);

またはより良い:

fgets(stringNum, sizeof stringNum, stdin);

おそらく、 に対しても同じことをしたいと思うでしょうenteredName

fgets(3)マニュアルページから:

この関数は、指定されたストリームから で fgets()指定された文字数より最大で 1 つ少ない文字を読み取り、それらを string に格納します。sizestr

あなたがやっているように、ヌルターミネータのために余分な配列エントリを予約する必要はありません -fgetsそれはそれ自身で正しく処理されます。

于 2013-06-21T05:10:15.007 に答える
0

問題は、読み取った文字列に a が含まれているかどうかがわからないことですnewline。が含まれていない場合newline、これは への次の呼び出しによって読み取られfgets、空の文字列が残ります。これを防ぐには、行newlineの末尾に文字が含まれているかどうかを確認します。を使用して読むだけではない場合はgetchar()、出来上がり!! (この解決策は、一般的にではなく、問題に対してのみ有効であることに注意してください)。このコードは、stringNum文字列を読み取った後に追加されます。

if(stringNum[strlen(stringNum)-1]!='\n')
{
    getchar();
}

これは、年齢が 2 桁の場合、文字fgetsではなく最後の桁まで読み取られるためです。newlineしたがって、最後の文字が でない場合に備えて読む必要があります\n。年齢が 1 桁の場合、元のプログラムは正常に動作します。

于 2013-06-21T05:13:42.777 に答える