2016-10-08 24 views
5

私はこの構造体をテストしており、getsの使用に関する警告が表示されます。誰かが代わりにfgetsを使用し、末尾を'\0'に置き換えると述べました。それを行うために私のコードをどのように変更することができますか?gets()をfgets()に置き換えます

void regCars(Car reg[], int *pNrOfCars) { 
    char again[WORDLENGTH] = "yes", model[WORDLENGTH], tmp[WORDLENGTH]; 
    int year, milage; 

    while (strcmp(again, "yes") == 0) { 
     printf("Enter model:"); 
     gets(model); 
     printf("Enter Year:"); 
     gets(tmp); 
     year = atoi(tmp); 
     printf("Enter milage:"); 
     gets(tmp); 
     milage = atoi(tmp); 
     reg[*pNrOfCars] = createCar(model, year, milage); 
     (*pNrOfCars)++; 
     printf("Continue? (yes/no)"); 
     gets(again); 
    } 
} 

答えて

0

あなたはユーティリティ関数2つの引数を取りmygets()を書くことができます質問と回答を読み取ります

char *prompt(const char *message, char *dest, size_t size) { 
    printf("%s ", message); 
    fflush(stdout); 
    /* read a line from standard input and strip the linefeed if any */ 
    if (fgets(dest, size, stdin)) { 
     dest[strcspn(dest, "\n")] = '\0'); 
     return dest; 
    } 
    return NULL; 
} 

void regCars(Car reg[], int *pNrOfCars) { 
    char model[WORDLENGTH], tmp[WORDLENGTH]; 
    int year, milage; 

    for (;;) { 
     if (!prompt("Enter model:", model, sizeof mode)) 
      break; 
     if (!prompt("Enter year:", tmp, sizeof tmp)) 
      break; 
     year = atoi(tmp); 
     if (!prompt("Enter milage:", tmp, sizeof tmp)) 
      break; 
     milage = atoi(tmp); 
     reg[*pNrOfCars] = createCar(model, year, milage); 
     (*pNrOfCars)++; 
     if (!prompt("Continue? (yes/no)", tmp, sizeof(tmp)) 
      break; 
     if (strcmp(again, "yes") != 0) 
      break; 
    } 
} 

はまた、この機能がの大きさを取る必要があることに注意してくださいアレイがいっぱいになると入力を促すプロンプトが表示されなくなります。現在指定されている通り、gets()と同じ欠点があり、予期しない入力は未定義の動作を引き起こします。

+0

@Alex:受諾した回答をアップ投票してもよろしいですか? – chqrlie

0

ジャスト例えば

if (NULL != fgets(model, WORDLENGTH, stdin)) /* Read the string. */ 
{ 
    model[strcspn(model, "\r\n")] = '\0'; /* Cut off \n and/or \r, if any. */ 
} 
+0

私はこれがモデルのためだけであると思います。もしintとcharが掛け合わされていれば、それらをすべて見渡して\ nを置き換える関数がありますか? – xxFlashxx

+0

@Alex: 'fgets()'( 'get()')は "strings"だけを読み込みます。 "年"を読むには、 'gets(tmp)'を使います。これは、次のように置き換えることができます。 – alk

+0

私はfgets(モデル)の直後にif文を挿入しますか? – xxFlashxx

1

を行うそれは見た目より少しトリッカーです。あなたが長すぎる入力で切り捨てられた行を処理し、それを有効として扱うなら、fgets()でgetsを置き換えるだけの点はあまりありません。定義されていない動作を間違った動作に置き換えただけです。ポインタをコピー先の配列とそのサイズに:あなたは出力prompt()機能でより多くのコードを因数分解することができます

char *mygets(char *dest, size_t size) { 
    /* read a line from standard input and strip the linefeed if any */ 
    if (fgets(dest, size, stdin)) { 
     dest[strcspn(dest, "\n")] = '\0'); 
     return dest; 
    } 
    return NULL; 
} 

void regCars(Car reg[], int *pNrOfCars) { 
    char model[WORDLENGTH], tmp[WORDLENGTH]; 
    int year, milage; 

    for (;;) { 
     printf("Enter model:"); 
     if (!mygets(model, sizeof mode)) 
      break; 
     printf("Enter year:"); 
     if (!mygets(tmp, sizeof tmp)) 
      break; 
     year = atoi(tmp); 
     printf("Enter milage:"); 
     if (!mygets(tmp, sizeof tmp)) 
      break; 
     milage = atoi(tmp); 
     reg[*pNrOfCars] = createCar(model, year, milage); 
     (*pNrOfCars)++; 
     printf("Continue? (yes/no)"); 
     if (!mygets(tmp, sizeof(tmp)) 
      break; 
     if (strcmp(again, "yes") != 0) 
      break; 
    } 
} 

if(fgets(line, sizeof(line), fp)) 
{ 
    if(!strchr(line, '\n')) 
    { 
     /* line is too long, what you do is up to you, but normally 
     we will discard it */ 
     int ch; 

     while((ch = fgetc(fp)) != EOF) 
     if(ch == '\n') 
      break; 

    } 
    else 
    { 
     /* line is a normal line with a trailing '\n' (gets trims the '\n')   */ 
    } 
} 
+0

長い行を破棄する必要はありません。また、長い行は、コンピュータプログラムによって書き込まれたテキストファイルで頻繁に発生します。 'fgets()'はそれらを読むことができます...それはもっと多くの呼び出しとそれを扱うロジックを必要とします。 – Peter

+0

有効な行に制限がない場合、fgets()は入力関数ではありません。もちろん、長すぎるラインの意味は状況によって決まり、時にそれを破棄するのは間違っています。サイレントに切り捨てて残りを完全な行と区別できないようにすることは、ほとんど正しい動作ではありません。 –

関連する問題