std::scanf, std::fscanf, std::sscanf
| ヘッダ <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 に従って解釈し、結果を指定された場所に格納します。
stream からデータを読み取ります。buffer からデータを読み取ります。パラメータ
| stream | - | 読み取り元の入力ファイルストリーム |
| buffer | - | 読み取り元のヌル終端文字列へのポインタ |
| format | - | 入力の読み取り方法を指定するヌル終端文字列へのポインタ |
| ... | - | 受け取り引数 |
format 文字列は以下から構成されます。
- 空白以外のマルチバイト文字 (ただし
%を除く): 書式文字列中のそのような各文字は、入力ストリームからちょうど 1 つの同一の文字を消費するか、ストリームの次の文字が等しくない場合に関数を失敗させます。 - 空白文字: 書式文字列内の任意の空白文字は、入力から利用可能な連続する空白文字をすべて消費します (あたかも std::isspace をループで呼び出すかのように決定)。書式文字列中では
"\n"," ","\t\t"または他の空白に違いはないことに注意してください。 - 変換指定。各変換指定は以下の形式を持ちます。
- 導入文字
%。
- 導入文字
- (オプション) 代入抑止文字
*。このオプションが存在する場合、関数は変換結果をどの受け取り引数にも代入しません。
- (オプション) 代入抑止文字
- (オプション) 最大フィールド幅を指定する整数 (0 より大きい) 最大フィールド幅。すなわち、現在の変換指定によって指定された変換を行う際に関数が消費を許される最大文字数です。幅が指定されていない場合、
%sと%[はバッファオーバーフローを引き起こす可能性があることに注意してください。
- (オプション) 最大フィールド幅を指定する整数 (0 より大きい) 最大フィールド幅。すなわち、現在の変換指定によって指定された変換を行う際に関数が消費を許される最大文字数です。幅が指定されていない場合、
- (オプション) 長さ修飾子。受け取り引数のサイズ、すなわち実際の変換先の型を指定します。これは変換の精度とオーバーフローの規則に影響を与えます。デフォルトの変換先の型は変換型ごとに異なります (以下の表を参照)。
- 変換書式指定子。
以下の書式指定子が利用可能です。
| 変換 指定子 |
説明 | 期待される 引数の型 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 長さ修飾子→ | 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
|
文字 または 文字列 に一致します。
|
N/A | N/A | char* |
wchar_t* |
N/A | N/A | N/A | N/A | N/A |
s
|
非空白文字のシーケンス (文字列) に一致します。
| |||||||||
[set ]
|
set で指定された文字の集合からの空でない文字シーケンスに一致します。
| |||||||||
d
|
10 進整数 に一致します。
|
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 進整数 に一致します。
| |||||||||
i
|
整数 に一致します。
| |||||||||
u
|
符号なし10 進整数 に一致します。
| |||||||||
o
|
符号なし8 進整数 に一致します。
| |||||||||
xX
|
符号なし16 進整数 に一致します。
| |||||||||
n
|
これまでに読み取った文字数 を返します。
| |||||||||
a (C++11)A (C++11)eEfF (C++11)gG
|
浮動小数点数 に一致します。
|
N/A | N/A | float* |
double* |
N/A | N/A | N/A | N/A | long double* |
p
|
ポインタ を定義する処理系定義の文字シーケンスに一致します。
|
N/A | N/A | void** |
N/A | N/A | N/A | N/A | N/A | N/A |
| ノート | ||||||||||
|
変換指定子 変換指定子 固定幅整数型 (std::int8_t など) の正しい変換指定は、ヘッダ <cinttypes> で定義されています (ただし SCNdMAX, SCNuMAX などは 各変換指定子の動作の後にシーケンスポイント があります。これにより、同じ「シンク」変数に複数のフィールドを格納することができます。 指数部で数字が欠けた不完全な浮動小数点値を解析する場合、たとえば 変換指定が無効な場合、動作は未定義です。 | ||||||||||
戻り値
正常に代入された受け取り引数の数 (最初の受け取り引数が代入される前にマッチング失敗が発生した場合はゼロになる可能性があります)、または最初の受け取り引数が代入される前に入力失敗が発生した場合は 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 番目の %d はスペースやタブを消費します)。
%c などの先行空白を消費しない変換指定子は、書式文字列に空白文字を使用することで消費させるようにできます:
std::scanf("%d", &a);
std::scanf(" %c", &c); // ignore the endline after %d, then read a char
std::sscanf の一部の実装では std::strlen の呼び出しが含まれるため、実行時間が文字列全体の長さに線形になります。つまり、std::sscanf をループ内で呼び出して文字列の先頭から値を繰り返し解析する場合、コードが 2 次時間で実行される可能性があります (例)。
例
#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ß水";
// 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 digits (digits 5 and 6)
// %2lc: two wide characters, using multibyte to wide conversion
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 << "Converted " << ret << " fields:\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';
}
出力:
Converted 7 fields:
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、ファイルストリーム、またはバッファから書式付き入力の読み取り 変数引数リストを使用 (関数) |
| ファイルストリームから文字列を取得 (関数) | |
(C++11) |
stdout、ファイルストリーム、またはバッファに書式付き出力を表示 (関数) |
(C++17) |
文字シーケンスを整数または浮動小数点値に変換 (関数) |
scanf, fscanf, sscanf の C ドキュメント
| |