C言語関係掲示板

過去ログ

No.101.ch=getchar(); scanf("%c",&ch); 


No.544

7−2 問1 変形 何がおかしいのでしょうか?
投稿者---2児のオヤジ です。(2001/11/14 23:20:52)


お手数かけますが、下記教えて下さい。
#include <stdio.h>
#include <ctype.h>

int main(void)
{
int ch;
ch = 0;
while((ch =getchar()) != EOF)
{

if (isalnum(ch)){
printf("[%c]",ch);
}
else {
printf("%c",ch);
}

}
return(0);

}

で、
printf("%c",ch);
}

else {
     printf("[%c]",ch);
}
とすると、[] が出力されます。
宜しくお願いします。



No.547

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---shu(2001/11/15 14:14:40)


5−4.scanf()関数の注意事項
(2) 復改文字が残る

と、同じことが起こってるんではないでしょうか。
isalnum('\t') は 非なので[]だけ表示されるんだと思います。


No.549

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---ともじ(2001/11/15 17:04:10)


>5−4.scanf()関数の注意事項
>(2) 復改文字が残る
>
>と、同じことが起こってるんではないでしょうか。
>isalnum('\t') は 非なので[]だけ表示されるんだと思います。

ch=getchar(); でも、scanf("%c",&ch); と同様のことが起こりますね。
本編、追記しておきます。

No.548

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---shu(2001/11/15 14:36:09)


'\t' じゃなくて '\n' ですね

No.550

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---2児のオヤジ です。(2001/11/15 19:11:59)


shuさん、ともじさん、早いご指導ありがとうございます。
5−4.scanf()関数の注意事項 確認して、回避方法考えてみます。

ありがとうございました!!


No.551

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---ともじ(2001/11/15 20:19:58)


>5−4.scanf()関数の注意事項 確認して、回避方法考えてみます。

回避にはfflushを使ってください。

No.552

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---2児のオヤジ です。(2001/11/15 23:03:17)


>回避には fflush を使ってください。

どうも、出来そうにありません。(わかりません)

 <すでに標準入力がある場合には、入力バッファに残っている'\n'を処理するため、正常な入力が行われません> とありますが、

if  else では、まだ、バッファに残ってない様な気がします。

宜しくお願い致します。


No.553

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---ともじ(2001/11/15 23:53:51)


>どうも、出来そうにありません。(わかりません)

#include <stdio.h>
#include <ctype.h>
int main(void)
{
	int ch;
	ch = 0;
	
	while((ch =getchar()) != EOF) 
	{ 
		if (isalnum(ch)){
			printf("%c",ch);
		}
		else {
			printf("[%c]",ch);
		}
		putchar('\n');
		fflush(stdin);
	}

	return(0);
}


こんな感じでしょうか。


No.554

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---shu(2001/11/16 00:06:03)


> <すでに標準入力がある場合には、入力バッファに残っている'\n'を処理するため、正常な入力が行われません> とありますが、
>
>if  else では、まだ、バッファに残ってない様な気がします。

if (isalnum(ch) || ch == '\n') { printf("%c",ch); }
にすればいいんじゃないでしょうか?



No.556

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---2児のオヤジ です。(2001/11/16 01:14:55)


>if (isalnum(ch) || ch == '\n') { printf("%c",ch); }
>にすればいいんじゃないでしょうか?
>

どうも とおらないみたいです。

\nで改行してないので、\nの処理は必要ないと思います?

LINUXで再度テストしてみます。

お手数かけます。



No.558

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---shu(2001/11/16 12:04:18)


>>if (isalnum(ch) || ch == '\n') { printf("%c",ch); }
>>にすればいいんじゃないでしょうか?
>>
>
>\nで改行してないので、\nの処理は必要ないと思います?
>
>LINUXで再度テストしてみます。
>
>お手数かけます。

結局の入力している値は、なんなんでしょう。

LSI_C と BCC では、下記のソースで問題無く動きましたよ。

#include <stdio.h>
#include <ctype.h>

int main(void)
{
	int ch;
	
	while ((ch = getchar()) != EOF) {
		if (isalnum(ch) || ch == '\n') {
			printf("%c", ch);
		}
		else {
			printf("[%c]",ch);
		}
	}
	
	return(0);
}



No.559

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---2児のオヤジ です。(2001/11/16 18:38:24)


>結局の入力している値は、なんなんでしょう。

入力ミスでした、申しわけありません。
ちゃんと動きました。
でも、else側に [ ] を入れたりするのって、難しいですね。
もしも、(問1の)if側に [ ] があったら(フラッシュが)理解出来ませんでした。

ありがとうございました。

No.555

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---kikk(2001/11/16 01:00:43)


ども。


単純に改行文字を空読みするだけならばgetchar()でもOKです。

なお、ANSIの規格上、fflush()を入力ストリームに適用した場合の動作は
未定義ですが、期待どおりバッファをクリアしてくれる処理系もあるようです
(LSI-Cではバッファクリアするとマニュアルに書いてありますね)。


では。

No.557

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---ともじ(2001/11/16 09:06:56)


>なお、ANSIの規格上、fflush()を入力ストリームに適用した場合の動作は
>未定義ですが、期待どおりバッファをクリアしてくれる処理系もあるようです
>(LSI-Cではバッファクリアするとマニュアルに書いてありますね)。

おっしゃる通り、入力ストリームでは未定義ですね。
失礼しました。修正します。

No.568

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---ともじ(2001/11/19 17:24:33)


書き込みありがとうございます。

>単純に改行文字を空読みするだけならばgetchar()でもOKです。

「Cプログラミングの非常識」 技術評論社 河西朝雄著 では、
rewind(stdin); を使っていました。
rewindですと、処理系に依存なく使えるのでしょうか。


No.569

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---kikk(2001/11/20 00:41:17)


ども。


>rewind(stdin); を使っていました。
>rewindですと、処理系に依存なく使えるのでしょうか。

できません。VCではキーボードバッファをクリアできるとリファレンスに
明示的に書いてあるようですが、規格上はキーボードバッファをクリアできる
とはいっていません。

規格の範囲で問題を解決するには、ひとつひとつ読み飛ばすということになると
思います。

なお、以前紹介したC FAQにもこの問題は取り上げられています。

現実的な解決策としては、処理系依存な方法をコメントをつけるなどして使って
しまうのもありかもしれませんが、その場合も、処理系で動作が定義されて
いるかどうかは確認した方がよいかと。たとえば、BCCではfflush(stdin)も
rewind(stdin)も動作の明示的な規定はありません。
# 期待通り動くには動きますが。。

一般に、処理系依存なコードで簡単にプログラムの完成度を上げるか、規格に
こだわるかは、場合場合によると思います。


では。

No.574

Re:7−2 問1 変形 何がおかしいのでしょうか?
投稿者---ともじ(2001/11/20 17:00:22)


返信ありがとうございます。

>なお、以前紹介したC FAQにもこの問題は取り上げられています。
「標準入出力の入力バッファの読んでいない入力を捨てる一般的な方法
はないし、そんなことをするだけでは充分でない。読まれていない文
字は、オペレーティングシステムレベルのバッファにもため込まれて
いる可能性がある。\nが出るまで文字を読んでは捨てて、それから
cursesのflushinp()やシステム固有の技を使うことで済ますことがで
きるかもしれない。」

ここの部分ですね。あのFAQは以前読んだのですが、記憶に残っていま
せんでした。すみません。
scanf()やgetchar()の改行を残す問題も、なかなかやっかいですね。
何故、Cがこの仕様を放っておくのか、ちょっと疑問です。

あのFAQを読み直していたら、
「12.18:	scanfの%dを使って数字を読んで、文字列をgets()で読もうとしてい
	る。けれどコンパイラはgets()の呼び出しを飛ばしているようだ。

 A:	scanfの%dはおしりの改行は食べてくれない。もし入力の数のすぐ後
	ろに改行が来たら、その改行はgets()の入力としての条件を満足する。

	一般に、scanf()の呼び出しと、gets()(その他の入力ルーチンも)の
	呼び出しを混ぜて使ってはいけない。scanf()の改行の扱いが妙なの
	で必ずやっかいなことになる。scanf()ですべて読み込むか、scanf()
	を使わないかのどちらかである。」

というのがあって、これも遭遇したことはないのですが、同様に注意すべき
問題だと思いました。

>一般に、処理系依存なコードで簡単にプログラムの完成度を上げるか、規格に
>こだわるかは、場合場合によると思います。

とりあえず、本編を規格に忠実に確認したいと思います。
いろいろと有難うございました。

戻る


「初心者のためのポイント学習C言語」 Last modified:2002.01.11
Copyright(c) 2000-2002 TOMOJI All Rights Reserved