C 言語で getchar 関数を使用する
この記事では、C 言語で getchar 関数を使用する方法について複数の方法を示します。
C 言語で標準入力ストリームから 1 文字を読み込むために getchar 関数を使用する
関数 getchar は C ライブラリに含まれる標準的な入出力ユーティリティの一部です。文字の入出力操作には、fgetc、getc、fputc、putchar のような複数の関数があります。fgetc と getc は基本的には同等の機能を持っており、ファイルストリームポインタを取得して文字を読み込み、それを int 型にキャストした unsigned char として返します。
getchar は getc の特殊なケースであり、stdin ファイルストリームを暗黙のうちに引数として渡して文字を読み取ることに注意してください。したがって、getchar は引数を取らず、読み込んだ文字を int 型にキャストして返します。以下の例では、putchar 関数を用いて 1 文字を入力してそれを出力するという基本的なシナリオを示します。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int ch;
printf("Please, input a single character: ");
ch = getchar();
putchar(ch);
exit(EXIT_SUCCESS);
}
C 言語で文字列入力を読み込むために getchar 関数を使用する
あるいは、新しい行や EOF が現れるまで入力された文字列を読み込み、あらかじめ割り当てられた char バッファに格納するループを実装することもできます。ただし、この方法は同じ機能を実装したライブラリ関数である gets や getline の呼び出しに比べてパフォーマンスのオーバーヘッドがあることに注意してください。解決策の主な部分は、getchar 関数の戻り値が改行文字または EOF と等しくなくなるまで実行される while ループです。
この場合、サイズ - 20 文字の char 配列を任意に割り当てた。反復のたびに配列の最初の要素へのポインタを実装し、getchar の戻り値を代入します。最後に、printf 関数呼び出しでバッファを出力します。
#include <stdio.h>
#include <stdlib.h>
enum { SIZE = 20 };
int main(void) {
char buf[SIZE];
char *p;
int ch;
p = buf;
printf("Please, provide input: ");
while ((ch = getchar()) != '\n' && ch != EOF) {
*p++ = (char)ch;
}
*p++ = 0;
if (ch == EOF) {
printf("EOF encountered\n");
}
printf("%s\n", buf);
exit(EXIT_SUCCESS);
}
出力:
Please, provide input: string longer than 20 characters
string longer than 20 characters
前の例のコードは通常は正常に動作するかもしれませんが、バッファオーバーフローのバグやプログラムの異常終了を引き起こす可能性のあるエラーがいくつかあります。改行や EOF が発生するまでユーザ入力を処理しているので、固定サイズの char バッファに収まる保証はありません。どうしても固定サイズのバッファを使わなければならない場合は、入力サイズのカウントを保持し、容量に達したらバッファへの格納を停止する責任があります。
前のコードでこの問題を解決した後、バッファの内容を出力するために %s 指定子を使う printf 文を処理しなければならません。入力文字列の最後の文字がヌルバイトであるという保証はないので、ユーザ自身がバッファの最後にヌルバイトを挿入しなかった場合、printf 呼び出しはどこで止まればよいかわからないことに注意してください。以下のサンプルコードでは、以前のエラーを修正し、より良いデモのためにいくつかの行を追加しています。
#include <stdio.h>
#include <stdlib.h>
enum { SIZE = 20 };
int main(void) {
char buf[SIZE];
int ch;
size_t index = 0;
size_t chars_read = 0;
printf("Please, provide input: ");
while ((ch = getchar()) != '\n' && ch != EOF) {
if (index < sizeof(buf) - 1) {
buf[index++] = (char)ch;
}
chars_read++;
}
buf[index] = '\0';
if (ch == EOF) {
printf("EOF encountered\n");
}
if (chars_read > index) {
printf("Truncation occured!\n");
}
printf("%s\n", buf);
exit(EXIT_SUCCESS);
}
出力:
Please, provide input: string longer than 20 characters
Truncation occured!
string longer than
