ページ 11

getcharで文字列を扱う

Posted: 2011年10月15日(土) 15:21
by kerotan0820
以下の問題を解いています。

◯入力した文字列(半角)の各文字のASCIIコードを出力するプログラムを完成させなさい。

□出力例
文字を入力してください(半角)。>>ab
a のASCIIコードは 97 です。
b のASCIIコードは 98 です。


学校の、プログラミング言語応用、という科目で配られたプリントの問題なのですが、
進行が遅いので予習しています。
課題ではありません。

プリントの単元がgetcharの性質を理解するための単元のようなので、以下の通りの条件を設けて解いています。

・getchar を用いて入力をする
・文字数の制限なし(配列の宣言は不可)

いろいろ調べていると、こちらのサイトを見つけました。
ポインタを用る表示方法でした。

それを参考にしつつ組み始め、ポインタを用いて、入力した二文字にだけ対応して表示するプログラムでポインタの機能をテストしています。

コード:



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

main(void)
{
	int *c;

	printf("文字を入力してください(半角)。>>");
	c = getchar();
	
	printf("%c の ASCII コードは %d です。\n",(c),(c));
	printf("%c の ASCII コードは %d です。\n",(c+1),(c+1));	
}
このプログラムを実行し、 ab と入力してみたところ、

a の ASCII コードは 97 です。
e の ASCII コードは 101 です。

と表示されました。
何故 e に成ってしまうのでしょうか、分からず困っています。




これが解決したら、c が NULL でない限り、◯ の ASCII コードは ◯◯ です。
と繰り返し表示するように改良する予定です。

それなので、先程、
int *c=NULL
として、
if((c+5)==NULL) printf("NULLです\n");
としてみたのですが、 NULL と出ませんでした。

ポインタ c に保存された、 getchar からのアドレス? が空であるか、ソウでないか、というのを調べるにはどのような方法を使えば可能なのでしょうか。

ご教示いただけると幸いです。



□追記□
また、追記なのですが、学校ではポインタについてまだ一切学んでおりません。
突然ポインタを使用しなくてはならない問題が出るとは考えにくいのですが、ポインタを用いずして解く方法がありますでしょうか。

Re: getcharで文字列を扱う

Posted: 2011年10月15日(土) 15:34
by taketoshi
ポインタに足し算を行うと、その型のバイト数が足されることになります。

char型だと1が足され、int型だと4、doubel型だと8が足されます。


>このプログラムを実行し、 ab と入力してみたところ、
>a の ASCII コードは 97 です。
>e の ASCII コードは 101 です。
>と表示されました。
>何故 e に成ってしまうのでしょうか、分からず困っています。

int型のポインタに+1しているので、+4されてます。
なので、bではなく、eになってしまうのです。

Re: getcharで文字列を扱う

Posted: 2011年10月15日(土) 15:53
by softya(ソフト屋)
配列も文字列もポインタも必要がなくて、改行を検出するまでループさせてやるだけだと思います。

(1)~(3)をループにします。

(1)getcharで文字を得る
(2)文字が改行なら終了
(3)文字のASCIIコードを10進表示。

[追記]getchar()の戻り値はint型です。ポインタは必要ありません。

Re: getcharで文字列を扱う

Posted: 2011年10月15日(土) 16:58
by ISLe
一度に何文字入力しようとも、getcharは呼び出す度にひと文字ずつ文字コードを返します。
入力が尽きるとgetcharはEOFを返します。

改行で終了するかどうかは好みになると思います。
改行を入力したときの挙動は処理系によって異なる場合がありますが、入力は継続します。
コンソールで入力が尽きたことを示すには、WindowsではCtrl+z、Unix系ではCtrl+dでEOFを入力します。

Re: getcharで文字列を扱う

Posted: 2011年10月16日(日) 01:21
by kerotan0820
taketoshi さんが書きました:ポインタに足し算を行うと、その型のバイト数が足されることになります。

char型だと1が足され、int型だと4、doubel型だと8が足されます。
ご教示ありがとうございます。
ポインタの性質をすっかり忘れていました。
理解出来ました。
softya(ソフト屋) さんが書きました:配列も文字列もポインタも必要がなくて、改行を検出するまでループさせてやるだけだと思います。
まさか、と思いながらひと通りの処理を全てwhileでくくったところ、本当に解決しました。
ありがとうございます。
ISLe さんが書きました:一度に何文字入力しようとも、getcharは呼び出す度にひと文字ずつ文字コードを返します。
入力が尽きるとgetcharはEOFを返します。

改行で終了するかどうかは好みになると思います。
改行を入力したときの挙動は処理系によって異なる場合がありますが、入力は継続します。
コンソールで入力が尽きたことを示すには、WindowsではCtrl+z、Unix系ではCtrl+dでEOFを入力します。
詳しくありがとうございます。
呼び出すたびにひと文字ずつ文字コードを返すということを初めて知り、今回、プログラム完成に導くことが出来ました。
本当にありがとうございます。



一応、このプログラムで最初の質問は解決しました。

コード:

/* pra22.c */


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

main(void)
{
	int c;

	printf("文字を入力してください(半角)。>>");
	
	while(1)
	{
		c = getchar();
		if(c=='\n') break;
		printf("%c の ASCII コードは %d です。\n",c,c);
	}
}



このプログラムが完成した上で、このプログラムの動作について教えていただきたいのですが
getchar() で常に入力待ち状態が続いていて、入力されるたびにそれをバッファに溜め込んでいるということは分かりました。
しかし、何故、printf文では %c %d に対応する変数は ,c,c と指定しているのに、同じ c でも違う値が出力されるのでしょうか。
毎度入力された値の文字コードを返しているにしても、毎度違う変数に記憶する必要がないのが不思議です。

それと、whlie を使っているのに、一度 ab と入力するとプログラムが whlie を抜けてしまいます。
abをリターンキーで確定しているせいで、自動的に ¥n が付いてしまっているのでしょうか。
if(c == '¥n') break;
の条件をなくすとループがされたのでおそらくそうだろうと思ってはいるのですが。

Re: getcharで文字列を扱う

Posted: 2011年10月16日(日) 09:55
by softya(ソフト屋)
kerotan0820 さんが書きました:このプログラムが完成した上で、このプログラムの動作について教えていただきたいのですが
getchar() で常に入力待ち状態が続いていて、入力されるたびにそれをバッファに溜め込んでいるということは分かりました。
しかし、何故、printf文では %c %d に対応する変数は ,c,c と指定しているのに、同じ c でも違う値が出力されるのでしょうか。
毎度入力された値の文字コードを返しているにしても、毎度違う変数に記憶する必要がないのが不思議です。
最初のgetchar() でgetchar()内部の読み込みバッファにキー入力の値がリターンキーまでの何文字分も溜まります。
それを順番にgetchar() で読み出しているって感じでしょうか。
kerotan0820 さんが書きました: それと、whlie を使っているのに、一度 ab と入力するとプログラムが whlie を抜けてしまいます。
abをリターンキーで確定しているせいで、自動的に ¥n が付いてしまっているのでしょうか。
if(c == '¥n') break;
の条件をなくすとループがされたのでおそらくそうだろうと思ってはいるのですが。
リターンキーで改行コードが入力されます。
なにでif(c == '¥n') break;でループを抜けています。

Re: getcharで文字列を扱う

Posted: 2011年10月16日(日) 12:00
by kerotan0820
>>softya様

詳しく解説ありがとうございます。

おかげさまで理解することが出来ました。
本当にありがとうございました。