2017-12-24 22 views
-1

リンクリストノードを作成するプログラムを作成しています。その後、いくつかの関数(挿入、検索、更新、および印刷)を追加します。リンクされたリストには、番号、名前、および数量が含まれています。C:fgets関数が動作しないのはなぜですか?

main関数は、ユーザーに操作コードの入力を求め、関数が要求した操作を呼び出します。

main() 
{ 
     char code; 
     int c; 
     for(;;) 
     { 
      printf("i: insert\ns: search\nu: update\np: print\n"); 
      printf("Enter operation code: "); 
      scanf("%c",&code); 
      while((c=getchar())!= '\n'&& c!=EOF); 
      switch(code) 
       { 
        case 'i': insert(); 
         break; 
        case 's': search(); 
         break; 
        case 'u': update(); 
         break; 
        case 'p': print(); 
         break; 
        case 'q':return 0; 
        default: printf("Illegal code\n"); 
         break; 
       } 
      printf("\n"); 
     } 
} 

すべての機能が正しく動作します。しかし、insert関数では、ユーザからの文字列入力を得るためにfgets文を使用します。 (NAME_LEN = 25)

残念ながら、このコードは機能しません。プログラムはそれを示しています

i: insert 
s: search 
u: update 
p: print 
Enter operation code: i 
Enter part number: 2 
Enter name part: Enter quantity on hand: 3 

これが分かるように、名前の部分が欠落していました。

さらに、新しいノードを挿入した後、プログラムは自動的にデフォルトのケースをスイッチに表示します。

i: insert 
s: search 
u: update 
p: print 
Enter operation code: i 
Enter part number: 2 
Enter name part: Enter quantity on hand: 3 

i: insert 
s: search 
u: update 
p: print 
Enter operation code: Illegal code 

私には何が起こるか説明できますか?

+1

あなたは何が問題なのか理解していますか? – coderredoc

+1

scanfの代わりにfgetsを使用すると、scanfはinbufferの内容を残します。 –

+1

ヒント:「なぜ(Cライブラリ関数名を挿入してください)関数が機能しないのですか?」という質問をいつでも書くことができます。問題。 –

答えて

4

よくあるのは、fgetsが前の入力からstdinに残っている\nを消費しています。簡単な方法は、ダミーgetchar()を使用するか、空白以外の入力が得られるまでfgetsを使用することです。

scanfの後に1つは、getchar()を入れます。あなたはi

を入力します入力すると仮定し、あなたにもっと明確な説明を与えることを

scanf("%c",&code); 
getchar(); 
^^^^ 
Will consume the `\n`. 

はその後iは変数codeに格納されています。しかし、\nはどうですか? fgets()stdinからの入力の読み取りが開始されると、\nが停止します。 getchar()を使用すると、\nを消費しました。空白以外の文字は、\nまたはEOFまたはbufferがいっぱいになるまで、fgetsによって消費されます。

stdinを流す最もポータブルでクリーンな方法は、\n文字を少なくとも持っていなければなりません。そうでなければ、他のcharcaters(おそらくあなたの有効な入力)を食べるでしょう)。

int c; 
while ((c = getchar()) != '\n' && c != EOF); 

これは、ごみ入力が発生した場合や標準入力をクリアした場合に使用できます。

また、fgets機能が動作するかどうかを確認するには、返す内容を確認する必要があります。それはNULLを返しますか?そうでない場合は、それを確認し、理解してください。印刷時に出力が見られなかったという理由だけで、バッファはfgetsに失敗したわけではありません。


編集

質問最初にscanf("%c",&code)fgets権利があることを述べました。ここではscanf("%d",&new_node->number);fgetsの前にあることが編集上明らかですが、それはシナリオを変更しません。入力した番号(2ENTERを入力した後)の\nはまだそこにあり、fgetsがそれを消費します。だから、そこにダミーgetchar()を置くか、上に示したようにstdinのフラッシング技術を置く必要があります。

scanf("%d",&new_node->number); 
getchar(); 
^^^^ 
This consumes the stray `\n` 
+0

ここで 'while'ループは入力ストリームをクリアする標準的な方法ですが、入力ストリームに少なくとも改行文字が必要であることに注意してください。 –

+0

ありがとう、私は挿入機能を追加することを忘れています。私は今編集しました。また、私はあなたの助言に従って、私は違法な番号の問題を修正することができます。しかし、プログラムを実行させるためには、insert関数の最後に2つのgetchar()関数を追加する必要があります。私は何が起こるのか分からない。私に説明することはできますか? –

+0

インサート関数の 'fgets'関数について教えてください。 '\ n'を使う前に' getchar() 'を書くべきですか? –