プロが教えるわが家の防犯対策術!

getcharをしながらwhile文で出力すると一つ多く出力されるのです・・・。

変な現象に遭遇しました。1文字入力して「入力した文字は~です。」とxが入力されるまで繰り返してくださいというプログラムを書きました↓

#include <stdio.h>

main()
{
char a;
do {
a = getchar();
printf("入力した文字は%cです。",a);
}
while(a != 'x');
}

ところが実行して、たとえばキーボードのaを押してenterキーを押すと

入力した文字はaです。入力した文字は
です。

と表示されるのです!!「入力した文字はaです。」だけでいいのに1つ多く出力されます。このソースは間違ってますか?

すみません、教えてください(涙)

A 回答 (8件)

エコー関数だからですよっ

この回答への補足

エコー関数? なんでしょう・・・。すみませんm(_ _)m

補足日時:2010/05/24 23:39
    • good
    • 0

「aを押してenter」によって、「a」と「enter」の2文字が入力されているのです。


「enter」に対するgetcharで、変数aに'\n'が入り、それを表示すると改行されるため、
---
入力した文字は
です。
---
という結果になるのです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます!!

入力した文字は
です。

というわけの分からなかった出力が理解できました。

でも、意図したとおりに動いてくれません。どう書き換えればよいのでしょう・・・。

入力した文字はaです。
入力した文字はbです。
入力した文字はxです。

プログラムが終わる、みたいになってほしいのですが。

お礼日時:2010/05/24 23:38

getcharは入力した文字をそのまま返します。



> キーボードのaを押してenterキーを押すと

aの後でenterキーを押しているのだから、enterも入力されます。すなわち'\n'が入力されているので、printf文でも'\n'(改行)が出力されます。
getcharの入力の終りはscanf等のようなenterではなくて、ctrl+Zです。
    • good
    • 1
この回答へのお礼

ありがとうございます!!

enterというのも文字なのですね。\nが入力されているのですか。

それであの変な出力になったわけですね・・・。

それにしてもctrl+Zを押しても終わりません。なんででしょう(汗)

手軽に勉強できる「C machine」というソフトを使っています。

お礼日時:2010/05/24 23:35

このプログラムには間違いがあります. さて, どこでしょうか?


それはおいても, 「Ctrl+Z を押したら終わり」ってプログラムに書いてないにもかかわらず「Ctrl+Z を押したら終わり」って動作になったら, そっちの方が奇妙ですね.
    • good
    • 0
この回答へのお礼

教えに入っていただきありがとうございます!!

Ctrl+Zを押したらループから出るというのは確かに書いてないですね(^_^;

文字コード表を見て探したけどなぜかCtrlがありません。というか、Ctrlを押すとはどういうことなんだろう。文字コードにないのに・・・。

whileループを抜ける条件を二つ以上作れるのだろうか。

while(a != 'x' || a = 'Ctrl + z')

ものすごくおかしいし、二つのボタンを同時に押したらってどうやってプログラムで書くのでしょう。ううう、難しい。一回目がCtrlで二回目がzだったらという条件にするとか?

(*_*)

お礼日時:2010/05/24 23:51

>while(a != 'x' || a = 'Ctrl + z')



おそらくコンパイルエラーになるでしょう。
'Ctrl + z'は文字ではありません。

Ctrlキーは文字に割り当てられているワケではありませんから、単体で押したところでgetchar()では検出できません。
# 環境によってはCtrl+ZでなくCtrl+Dということもあったりしますが…。

Tacosanさんの書かれている間違いについては…
最近のまともなコンパイラなら警告出しているかと思われます。
ちなみに「C machine」とやらを試す気はありません。
    • good
    • 0
この回答へのお礼

ありがとうございます・・・。

Ctrlキーは文字ではないのですね。getchar()で検出する部分ではないのですか。

Tacosanのおっしゃっていたものが警告として出るかvisual C++ Express editionでビルドしてみましたが警告はでませんでした。

実行してみたら、Ctrl+Zと押すと^Zと出ました。もしかしたら、この二つの文字になったらループを抜けろってすればいいのでしょうか・・・。

お礼日時:2010/05/25 00:35

>visual C++ Express editionでビルドしてみましたが警告はでませんでした。



VC++ 2010 ExpressEditionで確認。
ワーニングレベルを引き上げないと出ないようです…。
# /W3から/W4へ引き上げ。

>Ctrl+Zと押すと^Zと出ました。もしかしたら、この二つの文字になったら

'^Z'ではないので念のため。
    • good
    • 0
この回答へのお礼

こんにちは。また回答していただいてありがとうございます!!

私のは2008の方ですが、ワーニングレベルを/W4に引き上げたら警告が二つでました。それを修正して警告が出ないようにしたのですが、プログラムの動作は変わりません・・・。何が間違っているのでしょう(>_<)

'^Z'はCtrl+Zを示す文字ではないのですね。危ない危ない(汗)

#include <stdio.h>

int main() /* 訂正1 main関数の戻り値を指定した */
{
char a;
do {
a = (char)getchar(); /* 訂正2 char型のキャスト演算子を使用してaに入る型を揃えた */
printf("入力した文字は%cです。",a);
}
while(a != 'x');
}

お礼日時:2010/05/25 10:02

(処理系依存の「回答」ですが・・)



#2, #3 さんの言われる 「enter」 を「飛ばして◆」しまえばいいのでは、・・。

http://www.bohyoh.com/CandCPP/C/Library/fflush.h …
http://www9.plala.or.jp/sgwr-t/lib/fflush.html

int a;

do{
a = getchar();

printf( "入力した文字は%cです。\n", a );

fflush( stdin ); // ◆

}while( a != 'x' );
    • good
    • 0
この回答へのお礼

ありがとうございます!!

fflush(stdin);

を追加したら

入力した文字は
です。

という変なのがなくなりました!! それにしても難しい関数ですね・・・。リンク先の説明が難しかったです。

おかげさまで解決した感があるのですが、

No.4のTacosanさんの「このプログラムには誤りがある」という指摘の謎が解けなくて不完全燃焼です(^^;

お礼日時:2010/05/25 10:11

あれ? fflush って, 入力ストリームに使っていいんでしたっけ>#7. まあ「処理系依存」って書いてあるからいいといえばいいけど....


なお, #4 で指摘した「間違い」は「getchar の返り値を char で受けている」ところです. getchar の返り値は int で受けなければならない. 出てる警告はおそらく「int から char に変換している」というものだろうと思うけど, キャストで無理やりつぶすのは本筋ではないです. この辺は getchar の説明を頑張って探せば出てくるはず.
    • good
    • 0
この回答へのお礼

たくさんありがとうございます!!

getcharを調べたらすぐに戻り値はint型とありました。なんで私が読んでいた本ではchar型にしていたのだろう。変な本ですね・・・。

お礼日時:2010/05/27 00:06

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