Namespaces
Variants

std:: scanf, std:: fscanf, std:: sscanf

From ja.cppreference.net
< cpp ‎ | io ‎ | c
ヘッダーで定義 <cstdio>
int scanf ( const char * format, ... ) ;
(1)
int fscanf ( std:: FILE * stream, const char * format, ... ) ;
(2)
int sscanf ( const char * buffer, const char * format, ... ) ;
(3)

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

1) stdin からデータを読み取ります。
2) ファイルストリーム stream からデータを読み取ります。
3) ヌル終端文字列 buffer からデータを読み取ります。

目次

パラメータ

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

format 文字列は以下のもので構成されます:

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

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

変換
指定子
説明 期待される
引数の型
長さ修飾子→ hh h なし l ll j z t L
C++11 以降のみ利用可能→ はい はい はい はい はい
%
リテラル % に一致します。
N/A N/A N/A N/A N/A N/A N/A N/A N/A
c

文字 または 文字 のシーケンスに一致します。

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

空白以外の文字のシーケンス(文字列)に一致します。

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

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

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

10進整数 に一致します。

  • 数値の形式は、std::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*
std::intmax_t* または std::uintmax_t*
std::size_t*
std::ptrdiff_t*
N/A
b (C++26)

符号なし 2進整数 に一致します。

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

整数 に一致します。

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

符号なし 10進整数 に一致します。

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

符号なし 8進整数 に一致します。

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

符号なし 16進整数 に一致します。

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

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

  • 入力は消費されません。代入カウントは増加しません。
  • 指定子に代入抑制演算子が定義されている場合、動作は未定義です。
a (C++11)
A (C++11)
e
E
f
F (C++11)
g
G

浮動小数点数 に一致します。

  • 数値の形式は、std::strtof が期待するものと同じです。
N/A N/A
float*
double*
N/A N/A N/A N/A
long double*
p

ポインタ を定義する実装定義の文字シーケンスに一致します。

  • printf ファミリの関数は、%p 書式指定子を使用して同じシーケンスを生成する必要があります。
N/A N/A
void**
N/A N/A N/A N/A N/A N/A
注釈

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

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

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

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

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

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

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

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

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

戻り値

正常に代入された受信引数の数(最初の受信引数が代入される前にマッチング失敗が発生した場合はゼロとなる場合あり)、または EOF 最初の受信引数が代入される前に入力失敗が発生した場合。

計算量

保証されていません。特に、一部の実装における std::sscanf は O(N) であり、ここで N = std:: strlen ( buffer ) [1] です。高性能な文字列解析については、 std::from_chars を参照してください。

注記

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

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

異なる行で入力された2つの整数(2番目の % d が最初の入力で残された改行を消費する)または同じ行でスペースまたはタブで区切られた2つの整数(2番目の % d がスペースまたはタブを消費する)を読み取ります。

The conversion specifiers that do not consume leading whitespace, such as % c , can be made to do so by using a whitespace character in the format string:
std::scanf("%d", &a);
std::scanf(" %c", &c); // %dの後の改行を無視し、その後charを読み込む

std::sscanfの一部の実装では std::strlen の呼び出しが含まれるため、実行時間が文字列全体の長さに対して線形になることに注意してください。これは、 std::sscanfをループ内で呼び出して文字列の先頭から値を繰り返し解析する場合、コードが二次時間で実行される可能性があることを意味します( 例 )。

例

#include <clocale>
#include <cstdio>
#include <iostream>
int main()
{
    int i, j;
    float x, y;
    char str1[10], str2[4];
    wchar_t warr[2];
    std::setlocale(LC_ALL, "en_US.utf8");
    char input[] = "25 54.32E-1 Thompson 56789 0123 56ß水";
    // 以下のように解析:
    // %d: 整数
    // %f: 浮動小数点値
    // %9s: 最大9文字の空白以外の文字列
    // %2d: 2桁の整数(桁5と6)
    // %f: 浮動小数点値(桁7、8、9)
    // %*d: どこにも保存されない整数
    // ' ': 連続する全ての空白
    // %3[0-9]: 最大3桁の数字列(桁5と6)
    // %2lc: 2つのワイド文字、マルチバイトからワイド変換を使用
    const int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
                                &i, &x, str1, &j, &y, str2, warr);
    std::cout << "変換されたフィールド数: " << ret << "\n"
                 "i = " << i << "\n"
                 "x = " << x << "\n"
                 "str1 = " << str1 << "\n"
                 "j = " << j << "\n"
                 "y = " << y << "\n"
                 "str2 = " << str2 << std::hex << "\n"
                 "warr[0] = U+" << (int)warr[0] << "\n"
                 "warr[1] = U+" << (int)warr[1] << '\n';
}

出力:

変換されたフィールド数: 7
i = 25
x = 5.432
str1 = Thompson
j = 56
y = 789
str2 = 56
warr[0] = U+df
warr[1] = U+6c34

関連項目

(C++11) (C++11) (C++11)
可変長引数リストを使用して stdin 、ファイルストリーム、またはバッファから
書式付き入力を行う
(関数)
ファイルストリームから文字列を取得する
(関数)
書式付き出力を stdout 、ファイルストリーム、またはバッファに
出力する
(関数)
(C++17)
文字シーケンスを整数値または浮動小数点値に変換する
(関数)
Cドキュメント for scanf , fscanf , sscanf