scanf() — データの読み取り

フォーマット

#include <stdio.h>
int scanf(const char *format-string, argument-list);

言語レベル

ANSI

スレッド・セーフ

はい

ロケール依存

この関数の振る舞いは、現行ロケールの LC_CTYPE カテゴリーおよび LC_NUMERIC カテゴリーの影響を受ける可能性があります。また、この振る舞いは、LOCALETYPE(*LOCALEUCS2) または LOCALETYPE(*LOCALEUTF) がコンパイル・コマンドに対して指定されている場合は、現行ロケールの LC_UNI_CTYPE カテゴリーの影響を受ける可能性もあります。詳細については、CCSID およびロケールの理解を参照してください。

説明

scanf() 関数は、標準入力ストリーム stdin から argument-list 内の各エントリーで指定された位置へ、データを読み取ります。各 argument は、 format-string 内の型指定子に対応する型の変数を指すポインターでなければなりません。 format-string は、入力フィールドの変換処理を制御し、 始まりと終わりが初期シフト状態のマルチバイト文字ストリングです。

format-string には、以下の 1 つ以上が含まれます。
  • isspace() 関数で指定された空白文字 (ブランクおよび改行文字など)。空白文字の場合、scanf() 関数は、空白ではない次の文字まで、入力内の連続したすべての空白文字を読み取りますが、 保管はしません。 format-string 内の空白文字 1 文字は、入力データ内の空白文字を複数組み合わせたものに相当します。
  • 空白ではない文字。ただし、パーセント記号文字 (%) は除く。空白ではない文字の場合、 scanf() 関数は、一致する空白ではない文字を読み取りますが、保管はしません。 stdin の次の文字が一致しない場合、scanf() 関数は終了します。
  • パーセント記号 (%) で始まる形式指定。 形式指定によって、scanf() 関数は、入力された文字を読み取り、指定された型の値に変換します。 値は、引数リスト内の引数へ割り当てられます。

scanf() 関数は、format-string を左から右へ読み取ります。 形式指定以外の文字は、stdin 内の文字シーケンスと一致することを想定しています。 stdin 内の一致した文字は走査されますが、保管はされません。 stdin 内の文字が format-string と矛盾する場合、scanf() は終了します。 矛盾する文字は、読み取られなかった場合と同様に、stdin に残ります。

最初の形式指定が見つかると、最初の入力フィールドの値が形式指定に従って変換され、 argument-list 内の最初の項目で指定された場所に保管されます。 2 つ目の形式指定によって、2 つ目の入力フィールドが変換され、 argument-list の 2 番目のエントリーに保管されます。この作業は、format-string の最後まで行われます。

入力フィールドは、最初の空白文字 (スペース、タブ、または改行) まで、 形式指定に従って変換できない最初の文字まで、 もしくはフィールド width に達するまでのすべての文字として定義されます。この内、最初に登場するものが優先されます。 形式指定のための引数が多すぎる場合、余分な引数は無視されます。 形式指定に対して引数が足りない場合は、予期しない結果が引き起こされることになります。

形式指定の形式は、以下のとおりです。

構文図を読む構文図をスキップする
>>-%--+---+--+-------+--+----+--type---------------------------><
      '-*-'  '-width-'  +-h--+         
                        +-L--+         
                        +-l--+         
                        +-ll-+         
                        +-H--+         
                        +-D--+         
                        '-DD-'         

形式指定の各フィールドは、単一文字または数字で、特殊な形式オプションを示します。 最後のオプションの形式フィールドの後に表示される type 文字は、入力フィールドが文字、ストリング、または数字として解釈されるかどうかを判別するものです。 最もシンプルな形式指定には、パーセント記号と type 文字のみが含まれます (例えば、%s)。

形式指定の各フィールドについては、以下で詳細に説明します。パーセント記号 (%) の後に、形式制御文字として意味を持たない文字が続いた場合、その振る舞いは予期できません。この振る舞いの 1 つの例外は %% です。パーセント記号文字を指定するには、%% を使用します。

ポインターの出力と走査には、次の制約事項が適用されます。
  • ポインターを出力し、同じ活動化グループから走査し直した場合、 走査し直したポインターは、比較により、出力したポインターと等しくなります。
  • scanf() ファミリー関数が異なる活動化グループによって出力されたポインターを走査する場合、 scanf() ファミリー関数はポインターを NULL に設定します。

IBM® i ポインターの使用について詳しくは、ILE C/C++ プログラマーの手引き (英語) を参照してください。

パーセント記号の後のアスタリスク (*) は、指定された type のフィールドとして解釈される、 次の入力フィールドの割り当てを抑止します。 フィールドは走査されますが、保管はされません。

width は正の 10 進整数で、stdin から読み取られる文字の最大数を制御します。 width を超える文字は変換されず、対応する 引数 へも保管されません。空白文字 (スペース、タブ、または改行)、または指定された形式に従って変換できない文字が、 width に達する前に発生すると、width より少ない文字が読み取られます。

オプションのサイズ修飾子 h、l、ll、L、H、D、および DD は、 受信側のオブジェクトのサイズを示します。 対応する引数が、整数を指すポインターではなく short 型整数を指すポインターである場合、 型変換文字 d、i、および n の前には、h がなければなりません。 また、long 型整数を指すポインターである場合は l、 long long 型整数を指すポインターである場合は ll がなければなりません。 同様に、対応する引数が、符号なし int を指すポインターではなく、符号なし short 型整数を指すポインターである場合、 型変換文字 o、u、x、および X の前には、h がなければなりません。 また、符号なし long 型整数を指すポインターである場合は l、 符号なし long long 型整数を指すポインターである場合は ll がなければなりません。 対応する引数が、浮動小数点ではなく double を指すポインターである場合、型変換文字 a、A、e、E、f、F、g、および G の前には、l がなければなりません。また、long double を指すポインターである場合は L、_Decimal32 を指すポインターである場合は H、_Decimal64 を指すポインターである場合は D、あるいは _Decimal128 を指すポインターである場合は DD がなければなりません。最後に、対応する引数が、1 バイト文字型を指すポインターではなく wchar_t を指すポインターである場合、 型変換文字 c、s、および [ の前には、l がなければなりません。 h、l、L、ll、H、D、または DD が他の型変換文字とともに表示される場合、 その動作は予期できません。

次の表に、type 文字とその意味を示します。

文字 入力される型 引数の型
d 符号付き 10 進整数 int を指すポインター。
o 符号なし 8 進整数 符号なし int を指すポインター。
xX 符号なし 16 進整数 符号なし int を指すポインター。
i 10 進、16 進、または 8 進整数 int を指すポインター。
u 符号なし 10 進整数。 符号なし int を指すポインター。
a、A、e、E、
f、F、g、G
10 進数以外の浮動小数点数の場合、strtod() 関数で想定されるものと同じ形式の、オプションで符号付きの浮動小数点数、無限大、または NaN。

10 進数浮動小数点数の場合、strtod64() 関数で想定されるものと同じ形式の、オプションで符号付きの浮動小数点数、無限大、または NaN。

浮動小数点を指すポインター。
D(n,p) パック 10 進数。 これは、オプションの記号 (+ または -) と、その後に続く一連の空でない桁、 オプションの 1 つ以上の 10 進数字の並び (小数点を含む場合がある) で構成されます。 ただし、10 進の接尾部は含まれません。 サブジェクト・シーケンスは、最初の非空白文字から始まる、入力ストリングの最長の初期サブシーケンスとして定義されています。 これが想定される形式です。 入力ストリングが空であるか、すべて空白文字から成っているか、 あるいは最初の非空白文字が符号、数字、または 10 進小数点文字以外である場合には、 サブジェクト・シーケンスには文字は含まれません。 decimal(n,p) を指すポインター。 2 進化 10 進数オブジェクトの内部表記は、 パック 10 進数データ型の内部表記と同じであるため、型文字 D(n,p) を使用できます。
c 文字。c が指定されると、通常スキップされる空白文字が読み取られます。 入力フィールドに十分な大きさの char を指すポインター。
s ストリング 入力フィールドに加えて、自動的に付加される終了ヌル文字 (¥0) を入れるのに十分な大きさの文字配列を指すポインター。
n stream またはバッファーから読み取られる入力はありません。 int を指すポインター。 ここに、scanf() を呼び出した点までの文字数、 stream またはバッファーから正常に読み取られた文字数が保管されます。
p 一連の文字に変換される void を指すポインター void へのポインター。
lc マルチバイト文字定数 wchar_t を指すポインター。
ls マルチバイト・ストリング定数 wchar_t ストリングを指すポインター。

スペース文字で区切られていないストリングを読み取るには、 大括弧 ([ ]) 内の文字を s (ストリング) 型文字で置換します。 対応する入力フィールドは、括弧内の文字セットで現れない最初の文字まで、読み取られます。セット内の最初の文字が脱字記号 (^) である場合は、結果は反転されます。入力フィールドは、残りの文字セット内に現れる最初の文字まで読み取られます。

終了ヌル文字 (¥0) を保管しないで、ストリングを保管するには、%ac をしてください。ここで、a は 10 進整数です。 このインスタンスでは、c 型文字は、引数が文字配列を指すポインターであることを意味します。 次の a 文字が、入力ストリームから指定された場所へ読み取られ、ヌル文字は追加されません。

%x 形式指定子の入力は、16 進数として解釈されます。

scanf() 関数は、各入力フィールドを文字ごとに走査します。 指定された width に達したか、または次の文字が指定されたように 変換できない場合は、空白文字に達する前に、特定の入力フィールドを読み取る のを停止します。指定と入力文字との間に矛盾が生じた場合は、次の入力フィールドは、まだ読み取られていない最初の文字で始まります。矛盾した文字 (もしあった場合) は、 読み取られていない文字と見なされ、次の入力フィールドの最初の文字、 または stdin での次の読み取り操作での最初の文字となります。

%lc および %ls の場合は、読み取られるデータを指定しますが、 これはマルチバイト・ストリングで、mbtowc への呼び出しの場合と同様に、ワイド文字に変換されます。

%a、%A、%e、%E、%f、%F、%g、および %G の各形式指定子の場合、 文字シーケンス INFINITY または NAN (大/小文字は無視されます) が許可され、 それぞれ、値 INFINITY または静止非数 (NaN) が生成されます。

代替の形式指定の形式は、以下のとおりです。
構文図を読む構文図をスキップする
>>-%--arg-number$--+---+--+-------+--+----+--type--------------><
                   '-*-'  '-width-'  +-h--+         
                                     +-L--+         
                                     +-l--+         
                                     +-ll-+         
                                     +-H--+         
                                     +-D--+         
                                     '-DD-'         

代替として、前述のダイアグラムで概要が示された形式指定を使用して、 引数リスト内の特定のエントリーを割り当てることも可能です。 この形式指定と以前の形式指定は、 同じ scanf() への呼び出しで混用しないようにします。 そうでないと、予期不能な結果になる場合があります。

arg-number は正整数定数で、この場合、1 は引数リスト内の最初のエントリーを示します。 arg-number は、引数リスト内のエントリー数より多くならないようにします。 そうでないと、予期しない結果になります。 arg-number はまた、NL_ARGMAX より多くならないようにします。

戻り値

scanf() 関数は、正常に変換され、割り当てられたフィールドの数を戻します。 戻り値には、読み取りは行われたが、割り当てられなかったフィールドは含まれません。

変換が行われていない場合に、ファイルの終わりを読み取ろうとすると、戻り値は EOF になります。 戻り値 0 は、フィールドが割り当てられなかったことを意味します。

エラー条件

割り当てられる引数の型が形式指定と異なる場合は、予測不能な結果になる可能性があります。 例えば、浮動小数点値を読み取り、それを型 int の変数に割り当てることは誤りであり、 予測不能な結果になります。

形式指定にあるよりも多くの引数が存在する場合は、余分な引数は無視されます。 形式指定に対して引数が足りない場合は、予期しない結果が引き起こされることになります。

書式ストリングに無効な形式指定が含まれている場合に、 定位置形式指定が使用されていると、errno が EILSEQ に設定されます。

定位置形式指定が使用され、十分な引数がない場合、errno は EINVAL に設定されます。

変換エラーが発生した場合、errnoECONVERT に設定される可能性があります。

この例では、さまざまなタイプのデータを走査します。
#include <stdio.h>
 
int main(void)
{
   int i;
   float fp;
   char c, s[81];
 
   printf("Enter an integer, a real number, a character "
          "and a string : ¥n");
   if (scanf("%d %f %c %s", &i, &fp, &c, s) != 4)
      printf("Not all fields were assigned¥n");
   else
   {
      printf("integer = %d¥n", i);
      printf("real number = %f¥n", fp);
      printf("character = %c¥n", c);
      printf("string = %s¥n",s);
   }
}
 
/*****************  If input is: 12 2.5 a yes,  *******************
**************  then output should be similar to:  ****************
 
Enter an integer, a real number, a character and a string :
integer = 12
real number = 2.500000
character = a
string = yes
*/
この例では、16 進整数を 10 進整数に変換します。 while ループは、入力値が 16 進整数でない場合に終了します。
#include <stdio.h>
 
int main(void)
{
   int number;
 
   printf("Enter a hexadecimal number or anything else to quit:¥n");
   while (scanf("%x",&number))
   {
      printf("Hexadecimal Number = %x¥n",number);
      printf("Decimal Number     = %d¥n",number);
   }
}
 
/***************  If input is: 0x231 0xf5e 0x1 q,  ****************
****************  then output should be similar to:  **************
 
Enter a hexadecimal number or anything else to quit:
Hexadecimal Number = 231
Decimal Number     = 561
Hexadecimal Number = f5e
Decimal Number     = 3934
Hexadecimal Number = 1
Decimal Number     = 1
*/
この例では、stdin から読み取り、 代替の定位置書式ストリングを使用してデータを割り当てます。
#include <stdio.h>
int main(int argc, char *argv[])
{
   int i;
   char s[20];
   float f;

   scanf("%2$s %3$f %1$d",&i, s, &f);

   printf("The data read was \n%i\n%s\n%f\n,i,s,f);

   return 0;
}

/***************  If the input is : test 0.2 100  *****************
**************  then the output will be similar to: ***************
 
The data read was 
100
test
0.20000
*/
 -------------------------------------------------------------------- 
この例では、マルチバイト文字ストリングをワイド Unicode ストリングに読み取ります。 この例は、LOCALETYPE(*LOCALEUCS2) または LOCALETYPE(*LOCALEUTF) のいずれかによってコンパイルできます。
#include <locale.h>
#include <stdio.h>
#include <wchar.h>

void main(void)
{
   wchar_t uString[20];

   setlocale(LC_UNI_ALL, "");
   scanf("Enter a string %ls",uString);

   printf("String read was %ls\n",uString);
}

/* if the input is : ABC
   then the output will be similiar to:

   String read was ABC

 */