🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

12223閲覧

C言語 stdinのバッファのクリア方法がわからないです・・・。

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2019/10/23 13:46

###C言語、標準入力(stdin)のバッファのクリア方法について

C言語始めたばかりの初心者です。C言語のバッファのクリアの方法がわかりません。教科書にはfflush(stdout)という方法が載っているのですが、それを使わないでお願いします。

###設問
画面イメージに従いプログラムを作成しなさい。
6文字以上入力された場合"ERROR:6文字以上です。"と画面にエラーを出力し再入力を求める機能です。

問題

画面イメージ
5文字までの文字列を入力してください
>abcde
入力したのは5文字です。入力した文字列はabcdeです。
5文字までの文字列を入力してください
>aaaaaaaaaaaaaaaaaaaaaa
ERROR:6文字以上です。
5文字までの文字列を入力したください。

**fgets関数を使う**

該当のソースコード

#include<stdio.h> //定数定義 #define ARRAY_SIZE 7 void Intrim(char *str){ char *p; p=strchr(str, '\n'); if(p !=NULL){ *p='\n'; } } int main(void){ char str[ARRAY_SIZE]; int n; while(*str !='\n'){ printf("5文字までの文字列を入力してください。>\n"); fgets(str, sizeof(str), stdin); n=strlen(str)-1; str[n-1]='\n'; if(*str =='\n'){ break; } if(n>7){ printf("ERROR:6文字以上です。"); }else{ printf("入力したのは%dです。\n", n); printf("入力した文字列は%dです。\n", str); } } return 0; }

試したこと

実行してみたら、aaaaaaaaaaaaaaaaaなどを入れた場合、バッファがクリアされずに入力された文字はaaaaa
入力された文字列はaaaa・・・・とエラーが表示されません。

補足情報(FW/ツールのバージョンなど)

fgets関数で取得した改行コード'\n'をstrchr関数でnull文字に変える事もやっています。
正直、自分で書いてみて今現在何をしているのかよくわからない状態です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/10/23 13:49

なぜfflashはだめなんでしょうか
cateye

2019/10/23 14:19 編集

strのサイズを7にしたのは何故でしょう?・・・・もっと大きく取って、6文字以上だったらエラーにすれば良いのでは?
thkana

2019/10/23 22:31

> raccyさん 質問の縛りは「fflush(stdout)は使うな」だから、コンパイラ限定してfflush(stdin)も...(あまり本気じゃありません)
pepperleaf

2019/10/24 13:28

> #define ARRAY_SIZE 7 これって決まり? 1000 とか、2000くらい指定してはダメ? そうすれば、一般的な入力ではまず、問題無いと思うのですが、、。
guest

回答2

0

実行してみたら、aaaaaaaaaaaaaaaaaなどを入れた場合、バッファがクリアされずに入力された文字はaaaaa

入力された文字列はaaaa・・・・とエラーが表示されません。

状況の分析が間違っています。エラーが表示されない原因はバッファがクリアされないから、ではありません。
バッファのクリアが問題になるとすれば設問で言えば

再入力を求める

の部分です。
そこではなく、

C

1 n=strlen(str)-1; 2 str[n-1]='\n'; 3 if(*str =='\n'){ 4 break; 5 } 6 if(n>7){

のあたりの処理が間違っているのでエラーの判別が出来ません。(出力表示もいろいろおかしいはずです)

なお、質問のコードは
printf("入力した文字列は%dです。\n", str);
となっているのですから

入力された文字列はaaaa・・・・と

なるわけがありません。試したのと違うコードを示されても有効なアドバイスは出来ませんよ。

投稿2019/10/23 23:01

編集2019/10/24 00:15
thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

サイズ指定で読み込んだ時に、行全部を読み込めなかった場合、残った文字を行末まで無視したいということだと思うので、

C

1while(getchar()!='\n');

です。

fgetsした後の処理は間違っています。
5文字ちょうど入力した場合、str"ABCDE\n\0"で、
6文字以上入力した場合は、"ABCDEF\0"と先頭6文字だけ入ります。
strの中に'\n'があるかどうかを判断して、5文字以下だったか、6文字以上だったかを判断します。

strの中に'\n'が無かった場合に、上記whileを実行して'\n'が来るまで読み捨てます。

これ以外にも間違っている部分があります。質問とは関係ないので、指摘はやめておきます。

また、間違いではないですが、#define ARRAY_SIZE 7としているのに、プログラム中に5とか6とか7とかの数字が出てくるのは、何だかなあと思います。

なお、入力に対するfflush()は規格的には未定義動作のはずです。実際には多くの場合は使えると思いますので、使えれば使えばいいかと思います。

投稿2019/10/23 14:23

otn

総合スコア85893

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/10/24 06:48

すごく丁寧に説明してくださりありがとうございます。 while(getchar()!='\n');を使えばバッファをクリアすることが出来るのですね!! 正直まだできていないのですが、頑張ります!!
otn

2019/10/24 11:18

バッファクリアではないです。「行末まで読み飛ばし」です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問