Namespaces
Variants

scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s

ja.cppreference.net より
< c | io
 
 
ファイル入出力
型とオブジェクト
        
関数
ファイルアクセス
(C95)
書式なし入出力
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

書式付き入力
 
ヘッダ <stdio.h>
int scanf( const char* format, ... );
で定義 (1) (C99 まで)
int scanf( const char* restrict format, ... );
(C99 以降)
int fscanf( FILE* stream, const char* format, ... );
(2) (C99 まで)
int fscanf( FILE* restrict stream, const char* restrict format, ... );
(C99 以降)
int sscanf( const char* buffer, const char* format, ... );
(3) (C99 まで)
int sscanf( const char* restrict buffer, const char* restrict format, ... );
(C99 以降)
int scanf_s(const char* restrict format, ...);
(4) (C11 以降)
int fscanf_s(FILE* restrict stream, const char* restrict format, ...);
(5) (C11 以降)
int sscanf_s(const char* restrict buffer, const char* restrict format, ...);
(6) (C11 以降)

さまざまなソースからデータを読み取り、それを format に従って解釈し、結果を指定された場所に格納します。

1) stdin
からデータを読み取ります。2) ファイルストリーム stream
からデータを読み取ります。3) ヌル終端文字列 buffer からデータを読み取ります。文字列の終端に達することは、fscanf
のファイル終端条件に達することと同等です。4-6) (1-3) と同じですが、%c、%s、および %[ 変換指定子はそれぞれ2つの引数 (通常のポインタと、受け取り配列のサイズを示す rsize_t 型の値。1 を使用して単一の char に読み取る場合は %c になる可能性があります) を期待する点、および以下のエラーが実行時に検出され、現在インストールされている 制約ハンドラ 関数を呼び出す点が異なります:
  • ポインタ型の引数のいずれかがヌルポインタである
  • format、stream、または buffer がヌルポインタである
  • %c、%s、または %[ によって書き込まれる文字数 (終端ヌル文字を含む) が、それらの変換指定子のそれぞれに提供された2番目の (rsize_t) 引数を超える場合
  • オプションで、未知の変換指定子など、検出可能なその他のエラー
すべての境界チェック関数と同様に、scanf_s、fscanf_s、および sscanf_s は、実装によって __STDC_LIB_EXT1__ が定義され、ユーザーが __STDC_WANT_LIB_EXT1__ を整数定数 1 に定義してから <stdio.h> をインクルードした場合にのみ使用できることが保証されます。

引数

stream - 読み取り元の入力ファイルストリーム
buffer - 読み取り元のヌル終端文字列へのポインタ
format - 入力の読み取り方法を指定するヌル終端文字列へのポインタ
... - 受け取り引数。


format 文字列は以下から構成されます:

  • % 以外の非空白マルチバイト文字: 書式文字列内のそのような各文字は、入力ストリームからまったく同じ1文字を消費するか、ストリーム上の次の文字が等しくない場合に関数を失敗させます。
  • 空白文字: 書式文字列内の任意の単一空白文字は、入力から連続するすべての空白文字を消費します (isspace をループで呼び出したかのように判定されます)。書式文字列内の "\n"、" "、"\t\t"、またはその他の空白文字の間に違いはないことに注意してください。
  • 変換指定。各変換指定は以下の形式を持ちます:
  • 導入 % 文字。
  • (オプション) 代入抑止文字 *。このオプションが存在する場合、関数は変換結果をどの受け取り引数にも代入しません。
  • (オプション) 最大フィールド幅 を指定する整数 (ゼロより大きい)。つまり、現在の変換指定で指定された変換を行う際に関数が消費することが許可される最大文字数です。幅が指定されていない場合、%s と %[ はバッファオーバーフローを引き起こす可能性があることに注意してください。
  • (オプション) 長さ修飾子。受け取り引数のサイズ、つまり実際の格納先の型を指定します。これは変換の精度とオーバーフローのルールに影響します。デフォルトの格納先の型は変換の種類ごとに異なります (以下の表を参照)。
  • 変換書式指定子。

以下の書式指定子が使用可能です:

変換
指定子
説明 期待される
引数の型
長さ修飾子→ hh h なし l ll j z t L
C99 からのみ利用可能→ はい はい はい はい はい
%
リテラル % にマッチします。
なし なし なし なし なし なし なし なし なし
c

1つの 文字 または 文字のシーケンス にマッチします。

  • 幅指定子が使用された場合、正確に 幅 文字にマッチします (引数は十分な領域を持つ配列へのポインタである必要があります)。
  • %s や %[ とは異なり、配列にヌル文字を追加しません。
なし なし
char*
wchar_t*
なし なし なし なし なし
s

非空白文字のシーケンス (文字列) にマッチします。

  • 幅指定子が使用された場合、最大 幅 文字目、または最初の空白文字まで (最初に現れる方) にマッチします。
  • マッチした文字に加えて常にヌル文字を格納します (そのため引数配列には少なくとも 幅+1 文字分の空きが必要です)。
[set ]

文字の set からの空でないシーケンスにマッチします。

  • set の最初の文字が ^ の場合、set に含まれないすべての文字がマッチします。
  • set が ] または ^] で始まる場合、] 文字も set に含まれます。
  • スキャンセット内の非初期位置の文字 - が [0-9] のように範囲を示す可能性があるかどうかは処理系定義です。
  • 幅指定子が使用された場合、最大 幅 までのみマッチします。
  • マッチした文字に加えて常にヌル文字を格納します (そのため引数配列には少なくとも 幅+1 文字分の空きが必要です)。
d

10進整数 にマッチします。

  • 数値の形式は、strtol が期待するものと同じで、10 引数に値 base を指定した場合と同様です。
signed char* または unsigned char*
signed short* または unsigned short*
signed int* または unsigned int*
signed long* または unsigned long*
signed long long* または unsigned long long*
intmax_t* または uintmax_t*
size_t*
ptrdiff_t*
なし
b (C23)

符号なし 2進整数 にマッチします。

  • 数値の形式は、strtoul が期待するものと同じで、2 引数に値 base を指定した場合と同様です。
i

整数 にマッチします。

  • 数値の形式は、strtol が期待するものと同じで、0 引数に値 base を指定した場合と同様です (基数は最初に解析された文字によって決まります)。
u

符号なし 10進整数 にマッチします。

  • 数値の形式は、strtoul が期待するものと同じで、10 引数に値 base を指定した場合と同様です。
o

符号なし 8進整数 にマッチします。

  • 数値の形式は、strtoul が期待するものと同じで、8 引数に値 base を指定した場合と同様です。
x
X

符号なし 16進整数 にマッチします。

  • 数値の形式は、strtoul が期待するものと同じで、16 引数に値 base を指定した場合と同様です。
n

これまでに読み取られた文字数 を返します。

  • 入力は消費されません。代入カウントはインクリメントされません。
  • 指定子に代入抑止演算子が定義されている場合、動作は未定義です。
a (C99)
A (C99)
e
E
f
F (C99)
g
G

浮動小数点数 にマッチします。

  • 数値の形式は、strtof が期待するものと同じです。
なし なし
float*
double*
なし なし なし なし
long double*
p

ポインタ を定義する処理系定義の文字シーケンスにマッチします。

  • printf 系関数は、%p 書式指定子を使用して同じシーケンスを生成する必要があります。
なし なし
void**
なし なし なし なし なし なし
ノート

n 以外のすべての変換指定子について、指定されたフィールド幅を超えず、かつ変換指定子が期待するものと正確に一致するか、またはそれが期待するシーケンスの接頭辞である最長の入力文字シーケンスが、ストリームから消費されます。この消費されたシーケンスの後の最初の文字 (存在する場合) は未読のまま残ります。消費されたシーケンスの長さがゼロであるか、消費されたシーケンスを上記のとおり変換できない場合、ストリームからの入力を妨げるファイル終端、エンコーディングエラー、または読み取りエラーがない限り、マッチング失敗が発生します。その場合は入力失敗です。

% 指定子を除き、入力項目 (または %n の場合は入力文字数) は最初に変換指定子に適した型に変換されます。* で代入が抑制されなかった場合、変換結果はまだ書き込まれていない次の引数が指すオブジェクトに書き込まれます。このオブジェクトが適切な型を持たない場合、または変換結果がオブジェクトで表現できない場合、動作は未定義です。

[、c、および n 以外のすべての変換指定子は、入力を解析しようとする前に、先頭の空白文字をすべて消費して破棄します (isspace を呼び出したかのように判定されます)。これらの消費された文字は、指定された最大フィールド幅にはカウントされません。

変換指定子 lc、ls、および l[ は、最初の文字が変換される前にゼロに初期化された mbstate_t オブジェクトを使用して mbrtowc を呼び出したかのように、マルチバイトからワイド文字への変換を実行します。

変換指定子 s と [ は、マッチした文字に加えて常にヌル終端文字を格納します。格納先配列のサイズは、指定されたフィールド幅より少なくとも1大きくなければなりません。格納先配列のサイズを指定せずに %s または %[ を使用することは、gets と同じくらい安全ではありません。

固定幅整数型 (int8_t など) の正しい変換指定は、ヘッダ <inttypes.h> で定義されています (ただし、SCNdMAX、SCNuMAX などは %jd、%ju などと同義です)。

各変換指定子の動作の後には シーケンスポイント があります。これにより、複数のフィールドを同じ「シンク」変数に格納できます。

指数部に数字がない不完全な浮動小数点値 (たとえば、変換指定子 "100er" で %f を解析する場合) を解析するとき、シーケンス "100e" (おそらく有効な浮動小数点数の最長の接頭辞) が消費され、マッチングエラーが発生します (消費されたシーケンスを浮動小数点数に変換できません)。"r" が残ります。一部の既存の実装はこのルールに従わず、"100" のみを消費するようにロールバックし、"er" を残します (例: glibc バグ 1765)。

変換指定が無効な場合、動作は未定義です。

変換指定が無効な場合、動作は未定義です。

戻り値

1-3) 正常に代入された受け取り引数の数 (最初の受け取り引数が代入される前にマッチング失敗が発生した場合はゼロになる可能性があります)、または最初の受け取り引数が代入される前に入力失敗が発生した場合は EOF。
4-6) (1-3) と同じですが、実行時制約違反がある場合も EOF が返されます。

計算量

保証されません。特に、一部の sscanf の実装は O(N) であり、ここで N = strlen(buffer) [1] です。

ノート

ほとんどの変換指定子は最初に連続する空白をすべて消費するため、次のようなコード

scanf("%d", &a);
scanf("%d", &b);

は、別々の行 (2番目の %d は最初の行が残した改行を消費します) または同じ行のスペースやタブで区切って (2番目の %d はスペースやタブを消費します) 入力された2つの整数を読み取ります。

%c のように先頭の空白を消費しない変換指定子も、書式文字列に空白文字を使用することで消費させることができます:

scanf("%d", &a);
scanf(" %c", &c); // consume all consecutive whitespace after %d, then read a char

例

#define __STDC_WANT_LIB_EXT1__ 1
#include <locale.h>
#include <stddef.h>
#include <stdio.h>

int main(void)
{
    int i, j;
    float x, y;
    char str1[10], str2[4];
    wchar_t warr[2];
    setlocale(LC_ALL, "en_US.utf8");

    char input[] = "25 54.32E-1 Thompson 56789 0123 56ß水";
    /* parse as follows:
       %d: an integer
       %f: a floating-point value
       %9s: a string of at most 9 non-whitespace characters
       %2d: two-digit integer (digits 5 and 6)
       %f:  a floating-point value (digits 7, 8, 9)
       %*d: an integer which isn't stored anywhere
       ' ': all consecutive whitespace
       %3[0-9]: a string of at most 3 decimal digits (digits 5 and 6)
       %2lc: two wide characters, using multibyte to wide conversion  */
    int ret = sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
                     &i, &x, str1, &j, &y, str2, warr);

    printf("Converted %d fields:\n"
           "i = %d\n"
           "x = %f\n"
           "str1 = %s\n"
           "j = %d\n"
           "y = %f\n"
           "str2 = %s\n"
           "warr[0] = U+%x\n"
           "warr[1] = U+%x\n",
           ret, i, x, str1, j, y, str2, warr[0], warr[1]);

#ifdef __STDC_LIB_EXT1__
    int n = sscanf_s(input, "%d%f%s", &i, &x, str1, (rsize_t)sizeof str1);
    // writes 25 to i, 5.432 to x, the 9 bytes "Thompson\0" to str1, and 3 to n.
#endif
}

出力例:

Converted 7 fields:
i = 25
x = 5.432000
str1 = Thompson
j = 56
y = 789.000000
str2 = 56
warr[0] = U+df
warr[1] = U+6c34

参考文献

  • C23 規格 (ISO/IEC 9899:2024):
  • 7.21.6.2 fscanf 関数 (p: TBD)
  • 7.21.6.4 scanf 関数 (p: TBD)
  • 7.21.6.7 sscanf 関数 (p: TBD)
  • K.3.5.3.2 fscanf_s 関数 (p: TBD)
  • K.3.5.3.4 scanf_s 関数 (p: TBD)
  • K.3.5.3.7 sscanf_s 関数 (p: TBD)
  • C17 規格 (ISO/IEC 9899:2018):
  • 7.21.6.2 fscanf 関数 (p: 231-236)
  • 7.21.6.4 scanf 関数 (p: 236-237)
  • 7.21.6.7 sscanf 関数 (p: 238-239)
  • K.3.5.3.2 fscanf_s 関数 (p: 430-431)
  • K.3.5.3.4 scanf_s 関数 (p: 432)
  • K.3.5.3.7 sscanf_s 関数 (p: 433)
  • C11 規格 (ISO/IEC 9899:2011):
  • 7.21.6.2 fscanf 関数 (p: 317-324)
  • 7.21.6.4 scanf 関数 (p: 325)
  • 7.21.6.7 sscanf 関数 (p: 326)
  • K.3.5.3.2 fscanf_s 関数 (p: 592-593)
  • K.3.5.3.4 scanf_s 関数 (p: 594)
  • K.3.5.3.7 sscanf_s 関数 (p: 596)
  • C99 規格 (ISO/IEC 9899:1999):
  • 7.19.6.2 fscanf 関数 (p: 282-289)
  • 7.19.6.4 scanf 関数 (p: 290)
  • 7.19.6.7 sscanf 関数 (p: 291)
  • C89/C90 規格 (ISO/IEC 9899:1990):
  • 4.9.6.2 fscanf 関数
  • 4.9.6.4 scanf 関数
  • 4.9.6.6 sscanf 関数

関連項目

stdin、ファイルストリーム、またはバッファから書式付き入力を読み取ります
可変引数リストを使用
(関数)
ファイルストリームから文字列を取得します
(関数)
stdout、ファイルストリーム、またはバッファに書式付き出力を出力します
(関数)
C++ ドキュメント scanf, fscanf, sscanf