int vscanf( const char* format, va_list vlist ); |
(1) |
(C++11以上) |
int vfscanf( std::FILE* stream, const char* format, va_list vlist ); |
(2) |
(C++11以上) |
int vsscanf( const char* buffer, const char* format, va_list vlist ); |
(3) |
(C++11以上) |
| | |
様々なソースからデータを読み込み、それを format
に従って解釈し、結果を vlist
によって定義される位置に格納します。
2) ファイルストリーム stream
からデータを読み込みます。
3) ヌル終端文字列 buffer
からデータを読み込みます。
[編集] 引数
stream
|
-
|
読み込む入力ファイルストリーム
|
buffer
|
-
|
読み込むヌル終端文字列を指すポインタ
|
format
|
-
|
入力の読み込み方法を指定するヌル終端文字列を指すポインタ。
書式文字列は以下から構成されます。
-
% を除く非ホワイトスペースマルチバイト文字。 書式文字列内のそのような文字はそれぞれ、入力ストリームから正確に同一の文字を���とつ消費します。 または、ストリームの次の文字が等しくなければ、関数を失敗させます。
- ホワイトスペース文字。 書式文字列内のあらゆる単一のホワイトスペース文字は、入力から利用可能な連続するすべてのホワイトスペース文字を消費します (isspace を繰り返し呼んだかのように判定されます)。 書式文字列内の "\n"、 " "、 "\t" またはその他のホワイトスペース文字の間で差はないことに注意してください。
- 変換指定。 各変換指定は以下の形式を持ちます。
-
- (オプション) 代入抑制文字
* 。 このオプションが存在する場合、関数はいかなる受け取り引数にも変換の結果を代入しません。
- (オプション) 最大フィールド幅、つまり現在の変換指定によって指定された変換を行うときに関数が消費することができる最大文字数を指定する、 (ゼロより大きな) 整数値。 幅が指定されない場合、 %s および %[ はバッファオーバーフローに繋がる可能性があることに注意してください。
- (オプション) 受け取り引数のサイズ、つまり実際の格納先の型を指定する、長さ修飾子。 これは変換の正確性やオーバーフローのルールに影響します。 デフォルトの格納先の型は変換の種類によってそれぞれ異なります (下の表を参照してください)。
-
以下の書式指定子が利用できます。
変換指定子
|
説明
|
引数の型
|
長さ修飾子
|
hh
(C++11)
|
h
|
なし
|
l
|
ll
(C++11)
|
j
(C++11)
|
z
(C++11)
|
t
(C++11)
|
L
|
%
|
% にマッチします。
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
c
|
文字または文字シーケンスにマッチします。
幅指定子が使用されている場合は、ちょうど 幅 個の文字にマッチします (引数は十分な空間を持つ配列を指すポインタでなければなりません)。 %s および %[ と異なり、配列にヌル文字を追加しません。
|
N/A
|
N/A
|
|
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
s
|
非ホワイトスペース文字の並び (文字列) にマッチします。
幅指定子が使用されている場合は、最大 幅 個の文字または最初のホワイトスペース文字どちらか先に現れたところまでマッチします。 マッチした文字に加えて必ずヌル文字が格納されます (そのため引数の配列は少なくとも文字 幅+1 個分の空間を持っていなければなりません)。
|
[ set]
|
set 内の文字の空でない並びにマッチします。
set の最初の文字が ^ の場合は、 set 内に無いすべての文字がマッチします。 set が ] または ^] で始まる場合は、 ] 文字も set 内に含まれます。 [0-9] のような、 set 内の先頭でない位置にある文字 - が範囲を表すかどうかは、処理系定義です。 幅指定子が使用されている場合は、最大 幅 個の文字にのみマッチします。 マッチした文字に加えて必ずヌル文字が格納されます (そのため引数の配列は少なくとも文字 幅+1 個分の空間を持っていなければなりません)。
|
d
|
10進整数にマッチします。
数値の書式は base 引数に値 10 を指定した strtol() が期待するものと同じです。
|
signed char* または unsigned char*
|
signed short* または unsigned short*
|
signed int* または unsigned int*
|
signed long* または unsigned long*
|
signed long long* または unsigned long long*
|
|
|
|
N/A
|
i
|
整数にマッチします。
数値の書式は base 引数に値 0 を指定した strtol() が期待するものと同じです (基数はパースされる最初の文字によって決定されます)。
|
u
|
符号なし10進整数にマッチします。
数値の書式は base 引数に値 10 を指定した strtoul() が期待するものと同じです。
|
o
|
符号なし8進整数にマッチします。
数値の書式は base 引数に値 8 を指定した strtoul() が期待するものと同じです。
|
x , X
|
符号なし16進整数にマッチします。
数値の書式は base 引数に値 16 を指定した strtoul() が期待するものと同じです。
|
n
|
それまでに読み込んだ文字数を返します。
入力は消費されません。 代入カウントをインクリメントしません。 指定子が代入抑制文字を持っている場合、動作は未定義です。
|
a , A (C++11) e , E f , F g , G
|
浮動小数点数にマッチします。
数値の書式は strtof() が期待するものと同じです。
|
N/A
|
N/A
|
|
|
N/A
|
N/A
|
N/A
|
N/A
|
|
p
|
ポインタを表す処理系定義の文字シーケンスにマッチします。
printf ファミリーの関数は %p 書式指定子を使用したとき同じシーケンスを生成するべきです。
|
N/A
|
N/A
|
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
N/A
|
n 以外のすべての変換指定子について、指定されたフィールド幅を超えない、変換指定子が期待する入力文字の最も長いシーケンス、または変換指定子が期待するシーケンスの最も長い接頭辞が、ストリームから消費されるものなります。 この消費されたシーケンスの後の最初の文字 (もしあれば) は読まれずに残されます。 消費されたシーケンスの長さがゼロの場合、または消費されたシーケンスが上で規定されている通りに変換できない場合は、マッチの失敗が発生します。 ただし、ファイル終端、エンコーディングエラー、または読み込みエラーによってストリームからの入力が妨げられていた場合は、入力の失敗になります。
[ 、 c および n 以外のすべての変換指定子は、入力のパースを試みる前に、すべての先行するホワイトスペース文字を消費して破棄します (isspace を呼んだかのように判定されます)。 これらの消費された文字は、指定された最大フィールド幅にカウントされません。
長さ指定子 l が使用されている場合、変換指定子 c 、 s および [ は、最初の文字が変換される前に、ゼロに初期化された mbstate_t オブジェクトを使用して mbrtowc() を呼んだかのように、マルチバイト文字からワイド文字への変換を行います。
変換指定子 s および [ はマッチした文字に加えて必ずヌル終端を格納します。 格納先の配列のサイズは指定されたフィールド幅よりも少なくとも1文字多くなければなりません。 格納先の配列のサイズを指定せずに %s または %[ を使用することは、 std::gets と同様に、安全ではありません。
固定幅の整数型に対する正しい変換指定は、ヘッダ <cinttypes> で定義されています (SCNdMAX, SCNuMAX などは %jd , %ju などの同義語ですが)。
変換指定子それぞれの動作後に副作用完了点があります。 これにより同じ「ゴミ箱」変数に複数のフィールドを格納することができます。
数字のない指数で終わる不完全な浮動小数点値をパースするとき、例えば変換指定子 %f で "100er" をパースするとき、シーケンス "100e" (有効な浮動小数点数の可能性がある最も長い接頭辞) が消費され、結果はマッチエラーとなり (消費したシーケンスは浮動小数点数に変換できません)、 "r" が残されます。 処理系によってはこのルールに従わず、ロールバックして "100" のみを消費し、 "er" を残します (glibc bug 1765)。
|
vlist
|
-
|
受け取り引数を格納している可変長引数リスト
|
[編集] 戻り値
読み込みに成功した引数の数、または失敗した場合は EOF。
[編集] ノート
これらのすべての関数は va_arg を少なくとも1回は呼び、戻った後 arg
の値は不定になります。 これらの関数は va_end を呼ばす、それは呼び出し元が行わなければなりません。
#include <iostream>
#include <cstdio>
#include <cstdarg>
#include <stdexcept>
void checked_sscanf(int count, const char* buf, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if(std::vsscanf(buf, fmt, ap) != count)
throw std::runtime_error("parsing error");
va_end(ap);
}
int main()
{
try {
int n, m;
std::cout << "Parsing '1 2'...";
checked_sscanf(2, "1 2", "%d %d", &n, &m);
std::cout << "success\n";
std::cout << "Parsing '1 a'...";
checked_sscanf(2, "1 a", "%d %d", &n, &m);
std::cout << "success\n";
} catch(const std::exception& e)
{
std::cout << e.what() << '\n';
}
}
出力:
Parsing '1 2'...success
Parsing '1 a'...parsing error
[編集] 関連項目