函式
<cstdio>

scanf

int scanf ( const char * format, ... );
從 stdin 讀取格式化資料
stdin 讀取資料,並根據引數 format 將它們儲存到附加引數所指向的位置。

附加引數應該指向已分配的物件,其型別由 format 字串中相應的格式說明符指定。

引數

format
C 字串,包含一個字元序列,用於控制如何處理從流中提取的字元
  • 空白字元:函式將讀取並忽略在下一個非空白字元之前遇到的任何空白字元(空白字元包括空格、換行符和製表符 -- 參見 isspace)。format 字串中的單個空白符會驗證從中提取的任意數量的空白字元(包括沒有)。
  • 非空白字元,格式說明符 (%) 除外:任何既不是空白字元(空格、換行或製表符)也不是格式說明符一部分(以%字元開頭)的字元,都會導致函式從流中讀取下一個字元,並將其與此非空白字元進行比較,如果匹配,則丟棄該字元,函式繼續處理 format 的下一個字元。如果字元不匹配,函式將失敗,返回並使流中後續的字元保持未讀狀態。
  • 格式說明符:由初始百分號 (%) 形成的序列表示一個格式說明符,它用於指定要從中檢索並存儲到附加引數所指向位置的資料的型別和格式。

一個格式說明符scanf遵循此原型

%[*][width][length]specifier

其中,末尾的說明符字元是最重要的組成部分,因為它定義了提取哪些字元、它們的解釋以及其相應引數的型別
說明符描述提取的字元
i整數任意數量的數字,可選地以符號 (+-).
) 開頭。預設假定為十進位制數字 (0-9),但0字首表示八進位制數字 (0-7),而0x 或 0X 表示十六進位制數字 ( (0-f).
)。有符號引數。
d u十進位制整數任意數量的十進位制數字 (0-9),可選地以符號 (+-).
d) 開頭。d 用於有符號引數,uu 用於無符號引數。
o八進位制整數任意數量的八進位制數字 (0-7),可選地以符號 (+-).
),可選地以符號開頭。無符號引數。
x十六進位制整數任意數量的十六進位制數字 (0-9, a-f, A-F),可選地以0x或 0X0x 或 0X 開頭,並且都可選地以符號開頭。無符號引數。+-).
),可選地以符號開頭。無符號引數。
f, e, g浮點數一系列十進位制數字,可選地包含一個小數點,可選地以符號 (+-) 開頭,並可選地後跟ee 或 E字元和一個十進位制整數(或 strtod 支援的其他一些序列)。
符合 C99 標準的實現也支援以 0x0X 開頭的十六進位制浮點格式。
a
c字元下一個字元。如果指定了非11 的寬度,函式將精確讀取寬度個字元,並將它們儲存在作為引數傳遞的陣列的連續位置中。末尾不會附加空字元。
s字串任意數量的非空白字元,在找到第一個空白字元時停止。一個終止空字元會自動新增到儲存序列的末尾。
p指標地址表示指標的字元序列。使用的特定格式取決於系統和庫的實現,但它與在 fprintf 中格式化%p所用的格式相同。
[字元]掃描集方括號之間指定的任意數量的字元。
一個不是第一個字元的破折號 (-) 在某些庫實現中可能會產生不可移植的行為。
[^字元]反向掃描集任意數量的字元,其中沒有一個是在方括號內指定為字元的。
n計數不消耗任何輸入。
到目前為止從 stdin 讀取的字元數被儲存在指向的位置。
%%一個%後跟另一個%% 匹配一個單獨的%.
% 字元。此說明符不儲存任何資料。請參閱獲取百分號字元。除了 %n 和 %%n外,任何說明符都應至少消耗一個字元。否則匹配失敗,掃描在此結束。

格式說明符還可以包含子說明符:星號 (*)、寬度長度(按此順序),它們是可選的,並遵循以下規範:
子說明符描述
*一個可選的起始星號表示資料將從流中讀取但被忽略(即,它不儲存在由引數指向的位置)。
寬度指定在當前讀取操作中要讀取的最大字元數(可選)。
長度以下之一hh, h, l, ll, j, z, t, L(可選)。
這會改變相應引數所指向的儲存的預期型別(見下文)。

這是一個圖表,顯示了儲存輸入資料的相應引數的預期型別(帶有和不帶有長度子說明符)
說明符
長度d iu o xf e g ac s [] [^]pn
(無)int*unsigned int*float*char*void**int*
hhsigned char*unsigned char*signed char*
hshort int*unsigned short int*short int*
llong int*unsigned long int*double*wchar_t*long int*
lllong long int*unsigned long long int*long long int*
jintmax_t*uintmax_t*intmax_t*
zsize_t*size_t*size_t*
tptrdiff_t*ptrdiff_t*ptrdiff_t*
Llong double*
注意:黃色行表示由 C99 引入的說明符和子說明符。
... (附加引數)
根據 format 字串,該函式可能需要一系列附加引數,每個引數都包含一個指向已分配儲存空間的指標,其中提取的字元的解釋將以適當的型別儲存。
這些引數的數量至少應與格式說明符儲存的值的數量相同。多餘的引數會被函式忽略。
這些引數應該是指標:要在一個普通變數上儲存scanfscanf 操作的結果,其名稱前應加上引用運算子 (&&)(參見示例)。

返回值

成功時,函式返回成功填充的引數列表項的數量。由於匹配失敗、讀取錯誤或到達檔案結尾,該計數可能與預期的項數相符,也可能更少(甚至為零)。

如果在讀取時發生讀取錯誤或到達檔案末尾,則會設定相應的指示器(feofferror)。並且,如果任一情況在任何資料被成功讀取之前發生,則返回 EOF

如果在解釋寬字元時發生編碼錯誤,函式會設定 errnoEILSEQ.

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* scanf example */
#include <stdio.h>

int main ()
{
  char str [80];
  int i;

  printf ("Enter your family name: ");
  scanf ("%79s",str);  
  printf ("Enter your age: ");
  scanf ("%d",&i);
  printf ("Mr. %s , %d years old.\n",str,i);
  printf ("Enter a hexadecimal number: ");
  scanf ("%x",&i);
  printf ("You have entered %#x (%d).\n",i,i);
  
  return 0;
}

此示例演示了可以使用scanf:
Enter your family name: Soulie
Enter your age: 29
Mr. Soulie , 29 years old.
Enter a hexadecimal number: ff
You have entered 0xff (255).


相容性

scanf 讀取的一些型別。特定的庫實現可能支援額外的說明符和子說明符。
這裡列出的是最新的 C 和 C++ 標準(均於 2011 年釋出)所支援的,但黃色的部分是由 C99 引入的(自 C++11 起才要求 C++ 實現支援),可能不被符合舊標準的庫所支援。

另見