C言語で標準入力(通常はキーボード)から1文字を入力するには、標準ライブラリ関数のgetchar()を用います。
C言語での入力について説明しています。標準入力から1文字の入力、書式付きの入力、1行の入力を行う方法について説明します。
C言語で標準入力(通常はキーボード)から1文字を入力するには、標準ライブラリ関数のgetchar()を用います。
#include <stdio.h>
int getchar(void);
getchar()は、標準入力の次の文字を返します。ファイル(テキスト・ストリーム)の終端に達するとEOFを返します。
getchar()を使って入力された文字数をカウントするプログラムをつくってみるとこうなります。
#include <stdio.h>
int main(int argc, char *argv[])
{
unsigned long c = 0UL;
while (getchar() != EOF) {
c++;
}
printf("%ld¥n", c);
return 0;
}
キーボードからEOFを入力する方法は、一般的にWindowsのコマンド・プロンプトならコントロール+Zで、UNIXならばコントロール+Dです。
C言語で標準入力から書式付きで入力を行うには、標準ライブラリ関数のscanf()を用います。scanf()は通称、スキャンエフと呼ばれます。
#include <stdio.h>
int scanf(const char *format, ...);
scanf()は、標準入力から文字を読み込み、formatで指定された形式に従って解釈し、以降の引数に結果を格納します。printf()の入力版ともいえる関数です。
formatには、後述するフォーマット文字列を指定します。format以外の引数は結果を格納するので全てポインタとなります。戻り値は、変換に成功し、代入が行われたデータの個数です。ファイルの終わりではEOFが返されます。
簡単な例を見てみましょう。入力された数字をそのまま出力するプログラムです。
#include <stdio.h>
int main(int argc, char *argv[])
{
int n;
printf("Please input number: ");
scanf("%d", &n);
printf("Your number is %d¥n", n);
return 0;
}
フォーマット文字列の形式は次のとおりです。
%[代入抑止文字][最大フィールド幅][長さ修飾子]変換文字
[]で括られたものは省略可能です。
代入抑止文字は*です。この指定を行うと、フォーマットに合わせて入力を読み込みますが、実引数に代入されません。
%*c%c
と指定してあり、"AB"と入力されたならば、1文字目のAがスキップされ、2文字目のBが取得されます。
最大フィールド幅には、入力の最大のバイト数を指定します。
%100s
とすれば、文字列を最大100バイト分読み込みます。100バイトを超えた部分は次の引数に受け継がれます。
長さ修飾子には、h, l(英小文字のエル), Lのいずれかが指定可能です。変換文字d, i, n, o, u, xの前につける場合、引数がintではなく、shortへのポインタであればhを、longへのポインタならばl(英小文字のエル)をつけることができます。変換文字e, f, gの前につける場合、引数がfloatではなくdoubleへのポインタならばl(英小文字のエル)を、long doubleへのポインタならばLをつけることができます。
scanf()では、空白文字などが入力の区切りとなります。入力の途中で、空白文字などが現れると、その時点で読み込みを中止して、次の変換文字へと進みます。ここでいう空白文字などとは、スペース文字、タブ、改行、復帰、垂直タブ、改ページです。
変換文字には以下のものがあります。
文字 | 入力データ | 引数の型 | 備考 |
---|---|---|---|
d | 10進数 | int * | |
i | 整数 | int * | 頭に0のつく8進、頭に0x, 0Xのつく16進も可。 |
o | 8進整数 | unsigned int * | 頭に0がついても、つかなくても可。 |
u | 符号なし10進整数 | unsigned int * | |
x | 16進整数 | unsigned int * | 頭に0x, 0Xがついても、つかなくても可。 |
c | 文字(*1) | char * | |
s | 文字列(*2) | char * | 文字列には'¥0'が付加される。 |
e,f,g | 浮動小数点数(*3) | float * | |
p | ポインタ値 | void ** | |
n | 読み込み文字数(*4) | int * | |
[...] | 文字セットのマッチ文字列(*5) | char * | 文字列には'¥0'が付加される。 |
[^...] | 文字セット以外のマッチ文字列(*6) | char * | 文字列には'¥0'が付加される。 |
% | %文字そのもの |
| 代入は行われない。 |
(*1) … 次の入力文字は、幅のフィールドによって与えられる個数まで、指定の配列に入れられる。この数のデフォルトは1。'¥0'は付加されない。空白文字の通常のスキップも行われない。次の非空白文字を読むには%1sを使う。
(*2) … 非空白文字の文字列。引用符のついていないもの。
(*3) … floatの入力書式は、符号(省略可)、小数点を含みうる数字の列、指数部(省略可)。指数部は、Eまたはeの後に符号の付きうる整数が付いたもの。
(*4) … この呼び出しにより、それまで読み込まれた文字の数を引数に書き込む。入力は読み込まれない。変換済み項目数もカウントアップされない。
(*5) … []の間に存在する文字からなる、空でない最長の文字列とマッチする。[]...]なら文字セットには]が含まれる。
(*6) … [^]の間に存在しない文字からなる、空でない最長の文字列とマッチする。[^]...]なら文字セットには]が含まれる(マッチした文字列には]が含まれない)
標準ライブラリ関数のgets()を使用すると、標準入力より1行の入力を行えます。ただし、この関数はバッファオーバーフローを防ぐことができないため、通常使われることはありません。書式は以下の通りです。
#include <stdio.h>
char *gets(char *string);
標準入力から改行('¥n')が現れるまでデータを読み込み、引数で渡されたstringに格納します。このとき改行文字は'¥0'に置き換えられます。戻り値には読み込んだ文字列が返されます。エラーが発生した場合はNULLが返されます。
gets()は、読み込む文字列の大きさを決めることができません。そのため、引数に用意した配列のサイズを超える入力がなされると、バッファオーバーフローを引き起こします。この現象を防ぐことができないため、通常gets()を使用することはありません。gets()の代わりには、fgets()を使うとよいでしょう。