scanf()

scanf() の一般的な形式は次のとおり。

scanf(制御文字列, ...);

制御文字列は printf() とよく似たフォーマット指定子とその他の文字からなる。「…」の部分は可変長の引数で、制御文字列内のフォーマット指定子と対応する。これらの引数はフォーマット指定子の指定する型のアドレスでなければならない。scanf() 自体は入力されたフィールドの数を返す。

フォーマット指定子

%c文字
%d10進数
%i10進数
%e浮動小数点数
%f浮動小数点数
%g浮動小数点数
%o8進数
%s文字列
%x16進数
%pポインタ
%nこれまで読み込まれた文字数に等しい整数値を受け取る
%u符号なし整数
%[]文字集合

%c と %n 以外については最大フィールド幅を指定できる。
注意しなくちゃいけないのは %s は文字列を読み込むけど、空白文字が現れるとそこで読み込みをやめてしまうこと。例えば、

This is a test.

という文字列を %s で読み込もうとしても、「This」しか読み込まれない。

#include

int main(void)
{
    char str[80];

    printf("Input string: ");
    scanf("%s", str);
    printf("%s\n", str);

    return 0;
}
takatoh@nightschool $ ./sample_8_6
Input string: This is a test.
This

こういう場合は代わりに gets() を使う。

文字集合(スキャン集合)

%[ ] は大カッコで囲まれた文字を入力する。これをスキャン集合と呼ぶ。例えば

%[ABC]

という指定は A、B、C の続く限り読み込まれる。ほかの文字が現れた時点で次のフォーマット指定子に移る。[ ] 内の最初に ^ をつけることで否定を意味する。

#include

int main(void)
{
    char str[80];

    printf("Input string: ");
    scanf("%[a-z]", str);
    printf("%s\n", str);

    return 0;
}
takatoh@nightschool $ gcc sample_8_6b.c -o sample_8_6
takatoh@nightschool $ ./sample_8_6
Input string: ABCdefGHI
�l,

ありゃ、文字化けする。なんかおかしいんだろうか。

フォーマット指定子内の*

フォーマット指定子に * をつけると、そのフィールドは読み込まれずに捨てられる。入力に不要な文字が含まれている場合に便利。

int first, second;
scanf("%d%*c%d", &first, &second);

に対して

123-456

という入力があったとすると、first には 123、second には 456 が入力される。捨てられるフィールドに対応する引数は不要。

#include

int main(void)
{
    int first, second;

    printf("Input: ");
    scanf("%d%*c%d", &first, &second);
    printf("%d %d\n", first, second);

    return 0;
}
takatoh@nightschool $ ./sample_8_6c
Input: 123-456
123 456

制御文字列内のその他の文字の働き

制御文字列内に空白文字がある場合、scanf() は空白文字でない文字が現れるまで空白文字を捨てていく。その他の文字がある場合、一致しない文字が現れるまでその文字すべてを捨てていく。

include

int main(void)
{
    int first, second;

    printf("Input: ");
    scanf("A%d% %d", &first, &second);
    printf("%d %d\n", first, second);

    return 0;
}
takatoh@nightschool $ gcc sample_8_6d.c -o sample_8_6d
sample_8_6d.c: In function ‘main’:
sample_8_6d.c:9:5: warning: unknown conversion type character 0x20 in format [-Wformat=]
     scanf("A%d% %d", &first, &second);
     ^
takatoh@nightschool $ ./sample_8_6d
Input: AAA123    456
0 0

あれ、これもうまくいかない。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください