プロが教える店舗&オフィスのセキュリティ対策術

はじめまして。
現在c++を勉強し始めて1週間の初心者です。
fflush(stdin)について質問です。下記のプログラムで小文字入力したアルファベット1文字を大文字に変換して出力しています。方法(1)ではgetchar()関数とputchar()関数を使用していますがどうしてこの場合にはfflush(stdin)が必要となり、方法(2)のprintf()関数とscanf()関数を使用した場合はfflush(stdin)が必要ないのでしょうか?どなたか私のような初心者でも分かるように詳しく説明してもらいたいです。
何故かプログラムを書いているとprintf()とscanf()がよく混乱します。原因として、printf()を先に書く場合と、scanf()を先に書く場合が有るからだと思っているのですが、まだよく理屈の理解ができません。なので出来ればこれらの関数についても基本的な概念を教えていただきたいです。それと方法(2)では何故最後にscanf(%c):が無くても良いのかも良く理解できません。
どなたか是非とも回答宜しくお願いします。

#include <stdio>
main void()
{
方法(1)
printf("\n文字を1つ入力してください:");
fflush(stdin);
   char ch=getchar();
ch=ch-32;
putchar(ch);

   方法(2)
printf("\n文字を1つ入力してください:")
//fflush(stdin);必要なし???
   char ch;
scanf("%c",&ch);
ch=ch-32;
printf("%c",ch);
   //scanf(%c):???
}

A 回答 (6件)

それぞれの関数の説明は、リファレンスを参照すれば、わかると思いますよ。



関数の使い方は、リファレンスを参照する習慣をつけましょう。

その上で、何が質問したいのか、よくまとめてみてください。

たぶん、自力解決出来るのでは、ないかと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。プログラマーとして自力解決できる力は私も必要なことではないかとおもいます。ありがとうございました。

お礼日時:2009/02/11 07:42

方法(1)で、fflush(stdin)は不要のはずですが、無いとどうなりますか?



また、scanfという関数は使い方が非常に難しいので、初心者は絶対に使ってはいけません。とりあえずその存在を忘れた方が良いです。
同じようなことをしたい場合は、
char buf[200];
fgets(stdin,sizeof buf,buf);
sscanf(buf,"・・・・・",・・・・・);
のようにfgets+sscanfの組み合わせで使います。

あと、getchar()の値はint型なので、char chでなく int ch とします。

この回答への補足

回答ありがとうございます。getchar()の値はint型というのは某サイトにも同じことが書かれていたのを見たことがあります。しかしchar chでも正常に起動すのですが何故でしょうか?私はvs2005のc++を使っています。

補足日時:2009/02/11 07:37
    • good
    • 0

うん, 私も fflush は不要だと思う. ちなみに (1) で fflush を入れなかったらどんな動作になりますか?


以下おまけの突っ込み.
1. #include <stdio> じゃなくて #include <stdio.h>
2. 「小文字を大文字に変換する」ならそんな方法ではなく ctype.h を #include した上で tolower を使うべし.
3. 実は fflush は出力ストリームに対してのみ使うことができます. 従って (入力ストリームである) stdin に対して fflush を実行したときの結果は未定義となっています. 要するに「fflush(stdin); はやってはいけない」ということになります... ひょっとして fflush(stdout) ってしたかった?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。小文字を大文字に変換するときに<ctype.h を #include した上で tolower と実行?現在の知識では正直理解できませんが少し調べてみます。ありがとうございました。

お礼日時:2009/02/11 07:31

fflush(stdin);も、scanf(%c):も、このプログラムには不要です。


おそらく、どこかのサンプルプログラムを参考にしたのだと思いますが、そのサンプルプログラムのほうでは必要だっただけでしょう。

また、ストリーム入出力は奥が深いです。ちゃんと理解しようと思ったら、配列やらポインタやらOSの仕組みやら、いろいろな知識が必要です。
現段階で理解するのは無理かと思います。いまのところはこんなもんだと覚えておいて、いろいろは知識が身についてから、あらためて考え直すほうがいいとおもいます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。ストリームは奥が深いんですね。今はとりあいず貴方がおっしゃるようにこんなもんだと覚えておいて、printf()の場合はfflush.stdinは必要ないと暗記することにします。ありがとうございました。

お礼日時:2009/02/11 07:24

既に他の方も指摘していますが、


fflushについては、出力ストリーム以外の
ファイルディスクリプタに対しては使用してはいけません。
「不要かどうかではなく、禁止です。」

>どなたか私のような初心者でも分かるように詳しく説明して
噛み砕くことは必ずしもいい結果をもたらすとは思えないので、
特にその人の思い込みや普段の使い方から間違った説明を
しかねないと思うので、以下のHPで自力で調べて、
「ここの意味が分からない」ということろを改めて
質問されてはいかがでしょう?
# 特にCの規格書を1度も読んだ事がない人は、
# 一読することをお勧めします。
http://www.bohyoh.com/CandCPP/C/Library/index.html

> 方法(2)では何故最後にscanf(%c):が無くても良いのか
もともとの方法(1)に該当のscanfに対応する処理が
見あたりませんが。。。?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。不要ではなく禁止だったんですね。分かりました。添付して頂いたサイト、今後の参考にさせて頂きます。ありがとうございました。

お礼日時:2009/02/11 07:19

おそらく、fflush(stdin)ではなくfflush(stdout)ですね。



> printf("\n文字を1つ入力してください:");

とした場合、標準出力が行バッファリングまたはフルバッファリングの場合、getcharで読み込むを始める時点では文字列が出力し切れていない可能性があります。
いちいちfflush(stdout)を書くのが面倒であれば、プログラムの始めに、

setbuf(stdout, NULL);

としておくのも一つの手です。

ちなみに、fflush(stdin)とした場合の動作は未定義です。
必ずしも禁止ではありませんが、移植性は損なわれます。

参考URL:http://www.kijineko.co.jp/tech/superstitions/ffl …
    • good
    • 0
この回答へのお礼

回答ありがとうございます。fflush(stdin)以外にもsetbuf(stdout.NULL)って方法もあるんですね。とても勉強になりました。ありがとうございました。

お礼日時:2009/02/11 07:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!