fgetsとprintf

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tomo.xxx
記事: 13
登録日時: 11年前

fgetsとprintf

#1

投稿記事 by tomo.xxx » 10年前

この掲示板に何度かお世話になっているtomo.xxxです。
以下のようなコードと実行結果を得て、どうしてこういう実行結果になるのかが分からなかったので、質問させていただきました。

どうして、入力文字を増やすとprintfの表示部分が1度に何度も現れるのでしょうか?

コード:

#include <stdio.h>

int main(void)
{
	char str[5];

	while(1){
		printf("1:新規登録   2:追加登録    :");
		fgets(str, sizeof(str), stdin);
	}

	return 0;
}
実行結果:
1:新規登録 2:追加登録 :1
1:新規登録 2:追加登録 :2
1:新規登録 2:追加登録 :aa
1:新規登録 2:追加登録 :a
1:新規登録 2:追加登録 :vb
1:新規登録 2:追加登録 :nnn
1:新規登録 2:追加登録 :cccc
1:新規登録 2:追加登録 :1:新規登録 2:追加登録 :bbbb
1:新規登録 2:追加登録 :1:新規登録 2:追加登録 :aaaaaaaaaaa
1:新規登録 2:追加登録 :1:新規登録 2:追加登録 :1:新規登録 2:追加登録 :

アバター
usao
記事: 1887
登録日時: 11年前

Re: fgetsとprintf

#2

投稿記事 by usao » 10年前

たくさんの文字を入力したとき,
今回のfgets()が読み込まなかった分は入力バッファ(stdinの入力内容が蓄えられている場所.正式名称わからんけど)に残っているので
次回のfgets()が(新たな入力を待たずに)そこから読込を行っています.

・例えば aaaa(最後にEnter) と入力したとき,入力バッファの内容は {a,a,a,a,\n} となり,
 fgets( str, sizeof(str), stdin );の結果,先頭から{ a,a,a,a } が読み込まれ,入力バッファの内容が { \n } になります.

・ここでprintf()が走る
・次回のfgets(略)によって,やっと入力バッファが空になります.

・printf()が走る.
・fgets().今回は入力バッファが空なので,ユーザ入力待ちになる.

アバター
黒船
記事: 29
登録日時: 11年前
住所: 東京都目黒あたり

Re: fgetsとprintf

#3

投稿記事 by 黒船 » 10年前

fgets関数は指定された文字分しか読み込まないからです。
ここではsizeof(str) バイトつまり5バイト読み込みます。
ただ、fgets関数は読み込んだ文字の最後にNULL(\0)を付け足すので実質
4バイトまで読み込みます。4文字以上 例えば 6文字入力すると、fgets関数は
4文字読み取り終了し、ループしてまた上のprintfが実行され、残りの文字を
読み取り終了します。この問題を手っ取り早く解決するにはchar str[100];などに変更して
99文字まで読み込まえるようにすればいいと思います。
こうすれば相当長い文字を入力しない限り大丈夫です。
何文字入力しても大丈夫なようにしたいと
思っているのならば配列のサイズをあとから変えることができる
realloc関数を使って読み込んだ文字を配列に入れていけばいいでしょう。

閉鎖

“C言語何でも質問掲示板” へ戻る