名前空間
変種
操作

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

提供: cppreference.com
< cpp‎ | io‎ | c
 
 
 
C スタイルの入出力
関数
ファイルアクセス
直接入出力
書式なし入出力
書式付き入出力
scanffscanfsscanf
(C++11)(C++11)(C++11)
ファイル位置操作
エラー処理
ファイルに対する操作
 
ヘッダ <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 - 入力の読み込み方法を指定するヌル終端文字列を指すポインタ。

書式文字列は以下から構成されます。

  • % を除く非ホワイトスペースマルチバイト文字。 書式文字列内のそのような文字はそれぞれ、入力ストリームから正確に同一の文字をひとつ消費します。 または、ストリームの次の文字が等しくなければ、関数を失敗させます。
  • ホワイトスペース文字。 書式文字列内のあらゆる単一のホワイトスペース文字は、入力から利用可能な連続するすべてのホワイトスペース文字を消費します (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
char*
wchar_t*
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*
intmax_t* または uintmax_t*
size_t*
ptrdiff_t*
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
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 以外のすべての変換指定子について、指定されたフィールド幅を超えない、変換指定子が期待する入力文字の最も長いシーケンス、または変換指定子が期待するシーケンスの最も長い接頭辞が、ストリームから消費されるものなります。 この消費されたシーケンスの後の最初の文字 (もしあれば) は読まれずに残されます。 消費されたシーケンスの長さがゼロの場合、または消費されたシーケンスが上で規定されている通りに変換できない場合は、マッチの失敗が発生します。 ただし、ファイル終端、エンコーディングエラー、または読み込みエラーによってストリームからの入力が妨げられていた場合は、入力の失敗になります。

[c および n 以外のすべての変換指定子は、入力のパースを試みる前に、すべての先行するホワイトスペース文字を消費して破棄します (isspace を呼んだかのように判定されます)。 これらの消費された文字は、指定された最大フィールド幅にカウントされません。

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

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

固定幅の整数型に対する正しい変換指定は、ヘッダ <cinttypes> で定義されています (SCNdMAX, SCNuMAX などは %jd, %ju などの同義語ですが)。

変換指定子それぞれの動作後に副作用完了点があります。 これにより同じ「ゴミ箱」変数に複数のフィールドを格納することができます。

数字のない指数で終わる不完全な浮動小数点値をパースするとき、例えば変換指定子 %f"100er" をパースするとき、シーケンス "100e" (有効な浮動小数点数の可能性がある最も長い接頭辞) が消費され、結果はマッチエラーとなり (消費したシーケンスは浮動小数点数に変換できません)、 "r" が残されます。 処理系によってはこのルールに従わず、ロールバックして "100" のみを消費し、 "er" を残します (glibc bug 1765)。


... - 受け取り引数

[編集] 戻り値

代入に成功した受け取り引数の数 (最初の受け取り引数が代入される前にマッチの失敗が発生した場合はゼロになることがあります)、または最初の受け取り引数が代入されるまえに入力の失敗が発生した場合は EOF

[編集] ノート

ほとんどの変換指定子は、まずすべての連続するホワイトスペースを消費します。 以下のようなコードは

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

別の行に入力された2つの整数 (この場合、2番目の %d は1番目の %d によって残された改行を消費します)、または同じ行の空白またはタブで区切られた2つの整数 (この場合、2番目の %d は空白またはタブを消費します) を読み込みます。

%c などの先行するホワイトスペースを消費しない変換指定子は、書式文字列内でホワイトスペース文字を使用することでホワイトスペースを消費するようにできます。

std::scanf("%d", &a);
std::scanf(" %c", &c); // ignore the endline after %d, then read a char

[編集]

#include <iostream>
#include <clocale>
#include <cstdio>
 
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[] = u8"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
    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 << "\nx = " << x << '\n'
              << "str1 = " << str1 << "\nj = " << j << '\n'
              << "y = " << y << "\nstr2 = " << str2 << '\n'
              << std::hex << "warr[0] = U+" << warr[0]
              << " warr[1] = U+" << 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、ファイルストリームまたはバッファから書式付き入力を行います
(関数) [edit]
ファイルストリームから文字列を取得します
(関数) [edit]
stdout、ファイルストリームまたはバッファに書式付き出力を行います
(関数) [edit]
文字シーケンスを整数値または浮動小数点値に変換します
(関数) [edit]
scanf, fscanf, sscanfC言語リファレンス