- ベストアンサー
getcharの働きについて
- getchar()関数とは、1文字ずつ入力を受け取る関数であり、入力した文字を出力するためのputchar()関数と一緒に使われることが多い。
- getchar()関数を使って、入力した文字列をそのまま出力するプログラムを作成することができる。
- getchar()関数には異常終了しないため、入力がなくなるまで繰り返し動作する。また、マルチバイト文字や文字列も入力として扱うことができる。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
逆に、なぜ異常終了するかもしれないと感じたのですか? a を入力するときに a ENTER とキー入力したはずです。 このプログラムは getcharで 'a' を受け取る→putcharで 'a' を出力 getcahrで '\n'(改行文字) を受け取る→putcharで '\n' を出力 と、動作します。 元々複数文字読み込んでいるのです。その数が増えただけです。 「あ」の場合も(Shift_JISの場合) getcharで 「あ」の1バイト目 を受け取る→putcharで 「あ」の1バイト目 を出力 getcahrで 「あ」の2バイト目を受け取る→putcharで 「あ」の2バイト目 を出力 と2回に分けて処理されます。 あと □while ((ch = getchar()) != EOF) □□printf("入力は%c\n", ch); □□putchar(ch); は □while ((ch = getchar()) != EOF) □□printf("入力は%c\n", ch); のループと □□putchar(ch); に分かれます。 最後の文字化けしている箇所は ch=EOF の状態で putchar(ch)した結果だと思われます。
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
当然, バッファが一杯になれば「改行を押していないのに入力される」という状況になります. 何文字必要かは知りませんが, 500文字とか 2000文字とか入れればそのうちなんとかなるかもね.
お礼
ありがとうございました。
- notnot
- ベストアンサー率47% (4900/10358)
getchar() は「1文字入力する」や「1バイト入力する」という機能ではありません。 「入力された物から1バイト取り出す」という機能です。 入力された物が空(何もまだ入力されていないか、入力された物が取り出し尽くされた後)の場合は、新たに入力が発生しますが、どれだけのサイズをプログラムが入力するかは入力先によります。 端末だと(デフォルトでは)一行を入力するし、ファイルからの入力の場合は入力バッファのサイズ分だけ(4096とか8192バイトとか)入力されます。 説明を簡単にするためにEOFの説明を省くとこんな感じ。 1回目のgetchar()→端末から1行を入力して先頭1バイトを返す 2回目のgetchar()→さっきの残りの2バイト目を返す。もし残りが無かったのなら1回目と同じ 3回目のgetchar()→さっきの残りの3バイト目を返す。もし残りが無かったのなら1回目と同じ
お礼
詳しい解説をありがとうございました。
お礼
早々にとても明快なご回答、誠にありがとうございます。よく考えてみます。 後半の部分は、"{}"をつけるのを忘れていました。まだまだケアレスミスが多いですね、見直しを徹底します。
補足
>元々複数文字読み込んでいるのです。その数が増えただけです。 読み込まれた情報は、どこに格納されるのでしょうか。putchar()を使わないでgetchar()ばかりを実行していけば、格納場所にどんどん蓄積されていくのでしょうか、それとも、上書きされていって、putchar()が実行される直前の値だけ保持されているのでしょうか。この辺りのメカニズムが分かりません。ご教授頂けないでしょうか。 それから、 >「あ」の場合も(Shift_JISの場合) >getcharで 「あ」の1バイト目 を受け取る→putcharで 「あ」の1バイト目 を出力 >getcahrで 「あ」の2バイト目を受け取る→putcharで 「あ」の2バイト目 を出力 >と2回に分けて処理されます。 2バイト文字の場合も理解ができていないのでご教授願います。コードを調べたところ、 文字 あ S-JIS 0x82A0 JIS 0x2422 UniCode 0x3042 となっていますが、「1バイト目、2バイト目」、「上位バイト(ビット)、下位バイト(ビット)」とは、どちらから数えていくのでしょうか。上の「あ」のシフトJISの場合、コードは 0x82A0 となっていますが、2進数に変換した場合、 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 A 1010 B 1011 C 1100 D 1101 E 1110 F 1111 より、 0x82A0 → (2進数)1000 0010 1010 0000 となりますが、 (16進数)(A→)82A0(←B) (2進数)(C→)1000 0010 1010 0000(←D) とした場合、16進数ではAかBか、2進数ではCかDのどちらが上位・下位、1バイト目・2バイト目になるのでしょうか。 あと、whileループに{}をつけて実行したところ、実行結果は ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ 何か文字を入力して下さい。 (Ctrl+Zが入力されたら終了します。) 入力はa a入力は 入力はa a入力はb b入力はc c入力はd d入力はe e入力は ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ となりました。