scanf 関数の文字幅指定
更新 : 2007 年 11 月
ここでは、scanf_s などのセキュリティが強化されたバージョンを含めて、scanf の関数の書式指定文字列の解釈について説明します。これらの関数は、一般に入力ストリームが一連のトークンに分割されることを前提にしています。トークンは空白 (スペース、タブ、または改行) で区切られます。または数値型の場合は、数字テキストに変換できない最初の文字によって指定される数値データ型の自然な終端によって区切られます。ただし、文字幅の指定を使用して、トークンの自然な終端より前に入力の解析を停止することもできます。
width の指定は、% と型フィールド指定子の間の文字で構成されます。これには、width フィールドと呼ばれる正の整数、フィールドのサイズを示し、整数が short または long のどちらの型であるかなどのフィールドの種類を示す修飾子でもある 1 つ以上の文字が含まれます。このような文字はサイズ プリフィックスと呼ばれます。
Width フィールド
width フィールドには、フィールドに対して読み取る最大文字数を制御する正の 10 進整数を指定します。width を超える文字は変換されず、また対応する argument にも格納されません。width に達する前に、空白文字 (空白、タブ、または改行) が現れるか、指定された書式に従って変換できない文字が現れた場合は、読み取る文字数が width より少なくなります。
幅の指定は、scanf_s、wscanf_s などのセキュリティが強化されたバージョンに必要なバッファ サイズ引数とは完全に異なります。次の例では、幅の指定は 20 で、入力ストリームから最大 20 文字まで読み込むことを示します。バッファの長さは、最大文字数の 20 文字に終端文字 NULL 用の領域を加えて 21 文字です。
char str[21];
scanf("%20s", str, 21);
width フィールドを使用しない場合、scanf は文字列にトークン全体を読み込もうとします。指定されたサイズがトークン全体より小さい場合、対象文字列には何も書き込まれません。width フィールドが指定されていると、トークンの最初の width 文字が終端文字 NULL と共に対象文字列に書き込まれます。
Size プリフィックス
省略可能なプリフィックスである h、l、ll、I64、および L は、argument のサイズ (修飾する型文字に応じて、long 型または short 型の 1 バイト文字またはワイド文字) を示します。scanf 関数または wscanf 関数では、これらのプリフィックスを型指定子と一緒に使って、引数の解釈方法を指定できます。型プリフィックス I64 は Microsoft の拡張機能で、ANSI 互換ではありません。型指定子とその意味については、「scanf 関数の型フィールド文字」の「scanf 関数の型フィールド文字」の表を参照してください。
メモ : |
---|
h、l、および L プリフィックスは、char 型のデータと一緒に使用する場合は Microsoft の拡張機能です。 |
scanf 関数と wscanf 関数のサイズプリフィックスと型指定子
指定する型 |
プリフィックス |
型指定子 |
---|---|---|
double |
l |
e、E、f、g、または G |
long double (double と同じ) |
L |
e、E、f、g、または G |
long int |
l |
d、i、o、x、または X |
long unsigned int |
l |
u |
long long |
ll |
d、i、o、x、または X |
short int |
h |
d、i、o、x、または X |
short unsigned int |
h |
u |
__int64 |
I64 |
d、i、o、u、x、または X |
scanf 関数で 1 バイト文字 |
h |
c または C |
wscanf 関数で 1 バイト文字 |
h |
c または C |
scanf 関数でワイド文字 |
l |
c または C |
wscanf 関数でワイド文字 |
l |
c または C |
scanf 関数で 1 バイト文字列 |
h |
s または S |
wscanf 関数で 1 バイト文字列 |
h |
s または S |
scanf 関数でワイド文字列 |
l |
s または S |
wscanf 関数でワイド文字列 |
l |
s または S |
scanf_s 関数と wscanf_s 関数で h と l を使用する例を次に示します。
scanf_s( "%ls", &x, 2 ); // Read a wide-character string
wscanf_s( "%hC",&x, 2 ); // Read a single-byte character
scanf の関数のセキュリティが強化されていない関数を使用する場合は、前の引数のバッファ長を示すサイズ パラメータを省略します。
区切られていない文字列の読み取り
空白文字で区切られていない文字列を読み取るときは、型指定子 s (文字列) の代わりに角かっこ ([ ]) で囲んだ文字セットを指定します。角かっこで囲まれた文字セットは、制御文字列と呼ばれます。対応する入力フィールドは、制御文字列に含まれていない最初の文字が見つかるまで読み取られます。文字セットの最初の文字がカレット (^) の場合は、逆に作用します。つまり、入力フィールドは、角かっこで囲まれた文字セットに含まれている文字が見つかるまで読み取られます。
%[a-z] と %[z-a] は、%[abcde...z] と同等なものとして解釈されます。これは scanf 関数の共通の拡張機能ですが、ANSI 規格では不要です。
終端の NULL 文字がない文字列の読み取り
終端の NULL 文字 (\0) を除いた文字列を格納するには、%nc (n は 10 進整数) 指定を使います。この場合、型指定子 c は、引数が文字配列へのポインタであることを示します。次の n 文字が入力ストリームから指定の場所に読み取られます。NULL 文字 (\0) は追加されません。n を指定しない場合の既定値は 1 です。
scanf がフィールドの読み取りを停止する条件
scanf 関数は、各入力フィールドを文字単位でスキャンします。この関数は、空白文字に達する前でも、次の理由で特定の入力フィールドの読み取りを停止することがあります。
指定した文字幅に到達した。
次の文字を指定どおりに変換できない。
次の文字が、書式指定文字列の文字と一致しない。
次の文字が指定された文字セット内にない。
いずれの理由でも、scanf 関数が入力フィールドの読み取りを停止すると、その次の文字から、次の入力フィールドであると解釈されます。書式指定と一致しない文字があると、その文字は読み取られず、その文字が次の入力フィールドの先頭文字、または入力ストリームに対するその後の読み取り操作の先頭文字になります。
参照
参照
scanf、_scanf_l、wscanf、_wscanf_l