格式規格語法: printfwprintf 函式

各種 printfwprintf 函式皆會採用格式字串和選擇性引數,然後產生格式化的輸出字元序列。 格式字串包含零或多個「指示詞」,這是輸出的常值字元或是編碼的「轉換規格」,其會說明如何將輸出的引數格式化。 本文說明格式字串中用來為轉換規格進行編碼的語法。 如需這些函式的清單,請參閱資料流 I/O

轉換規格包含選擇性及必要欄位,形式如下︰

%[flags][width][.precision][size]type

每個轉換規格的欄位都是字元,或是表示特定格式選項或轉換規範的數字。 必要的 type 欄位會指定要套用至引數的轉換種類。 選擇性 旗標 寬度 有效位數 欄位可控制其他格式層面,例如前置空格或零、對齊和顯示的精確度。 size 欄位指定取用和轉換之引數的大小。

基本的轉換規格只包含百分比符號和一個 type 字元。 例如,%s 指定字串轉換。 若要列印百分比符號字元,請使用 %%。 如果百分比符號後接著的字元不代表任何格式欄位,則會叫用無效參數處理常式。 如需詳細資訊,請參閱 參數驗證

重要

針對安全性和穩定性,請確定格式轉換規格字串不是使用者定義的。 例如,考慮一個請使用者輸入名稱的程式,且該程式將輸入儲存在名為 user_name 的字串變數。 若要列印 user_name ,請勿執行此動作:

printf( user_name ); /* Danger! If user_name contains "%s", program will crash */

相反地,請這樣做:

printf( "%s", user_name );

注意

在 Visual Studio 2015 中,函 printf 式的 和 scanf 系列已宣告為 inline ,並移至 <stdio.h><conio.h> 標頭。 如果您要移轉較舊的程式碼,您可能會看到LNK2019與這些函式有關。 如需詳細資訊,請參閱 Visual C++ 變更歷程記錄 2003 - 2015

類型轉換規範

type 轉換規範字元指定要將對應的引數解譯成字元、字串、指標、整數還是浮點數。 type 字元是唯一必要的轉換規格欄位,且會在任何選擇性的欄位之後出現。

遵循格式字串的引數會根據對應的 type 字元和選擇性的 size 前置詞解譯。 使用 或 指定字元類型的 char 轉換, wchar_t 並使用 或 C 來指定 csS 單一位元組和多位元組或寬字元字串,視所使用的格式化函式而定。 使用 c 和 所指定的字元和字串引數會解譯為 printfchar*char 和依系列函式,或依系列函式來解譯為 wchar_twchar_t*wprintfs 使用 C 和 所指定的字元和字串引數會解譯為 printfwchar_t*wchar_t 和依系列函式,或依系列函式來解譯為 charchar*wprintfS 此行為是 Microsoft 特定的。 基於歷史原因,函 wprintf 式會使用 cs 來參考 wchar_t 字元,並 CS 指定窄字元。

整數型別,例如 shortint 、、 long longlong 、 及其 unsigned 變體,是使用 dio 、、 uxX 來指定。 使用 、 eAdoublelong doubleEfgFGfloat 浮點類型來 a 指定。 根據預設,除非它們是由 大小 前置詞修改,否則整數引數會強制 int 型別,而浮點引數則會強制設定為 double 。 在 64 位系統上, int 是 32 位值;因此,除非使用 或 I64 的大小 前置 ll 詞,否則 64 位整數會在格式化輸出時截斷。 使用平臺的預設指標大小所 p 指定的指標類型。

注意

Microsoft 特定:
與 和 wprintf 函式搭配 printf 使用時,、 ZsS 型別字符的類型字元和行為 cC 都是 Microsoft 延伸模組。 ISO C 標準會針對 c 窄字元和字串使用和 s 一致的方式,以及 SC 所有格式化函式中的寬字元和字串。

類型欄位字元

類型字元 引數 輸出格式
c 字元 搭配 printf 函式使用時,會指定單一位元組字元;搭配 wprintf 函式使用時,會指定寬字元。
C 字元 搭配 printf 函式使用時,會指定寬字元;搭配 wprintf 函式使用時,會指定單一位元組字元。
d 整數 帶正負號的十進位整數。
i 整數 帶正負號的十進位整數。
o 整數 不帶正負號的八進位整數。
u 整數 不帶正負號的十進位整數。
x 整數 不帶正負號的十六進位整數;使用 「 abcdef 」。
X 整數 不帶正負號的十六進位整數;使用 「 ABCDEF 」。
e 浮點 具有格式為 [ - ]d.dd e [] dd[ dd [ +|- d]的帶正負號值,其中 d 是一個十進位數, dddd 是一或多個十進位數,視指定的有效位數或預設 為 6,dd[ d ] 是兩或三個十進位數,視 指數的輸出格式 和大小而定。
E 浮點 e 格式相同,不同之處在于 E ,而不是 e 引進指數。
f 浮點 帶正負號的值,其格式為 [ - ] d . d,其中 dd 是一或多個十進位數。 小數點前面的位數取決於數字的大小,小數點後面的位數則取決於要求的精確度,或是預設為六。
F 浮點 f 格式相同,不同之處在于無限大和 NaN 輸出會大寫。
g 浮點 帶正負號的值會以 fe 格式顯示,無論哪個值和精確度都比較精簡。 e只有當值的指數小於 -4 或大於或等於 precision 引數時,才會使用格式。 會截斷尾端的零,僅當一或多個數字位於小數點後面時,才會顯示小數點。
G 浮點 g 格式相同,不同之處在于 E ,而不是 e ,會介紹指數(若適當)。
a 浮點 帶正負號的十六進位雙精確度浮點值,其格式為 [ - ] 0x h.hhhh p [ -|+ ] dd ,其中 h.hhhhh 是 mantissa 的十六進位數位(使用小寫字母),而 dd 是指數的一或多個數位。 指定小數點之後位數的精確度。
A 浮點 帶正負號的十六進位雙精確度浮點值,其格式為 [ - ] 0X h.hhhh P [ -|+ ] dd ,其中 h.hhhhh 是 mantissa 的十六進位數位(使用大寫字母),而 dd 是指數的一或多個數位。 指定小數點之後位數的精確度。
n 整數的指標 目前已成功寫入此資料流或緩衝區的字元數。 會將這個值儲存在整數中,該整數的位址會做為引數而受指定。 引數大小規格前置詞可以控制指向整數的大小。 n 指定名稱預設會停用;如需資訊,請參閱重要安全性注意事項。
p 指標類型 以十六進位數字顯示引數作為位址。
s String 當搭配 printf 函式使用時,會指定單一位元組或多位元組字元字串;當搭配 wprintf 函式使用時,會指定寬字元字串。 字元會顯示,直到第一個 null 字元或達到 precision 值為止。
S String 當搭配 printf 函式使用時,會指定寬字元字串;當搭配 wprintf 函式使用時,會指定單一位元組或多位元組字元字串。 字元會顯示,直到第一個 null 字元或達到 precision 值為止。
Z ANSI_STRINGUNICODE_STRING 結構 VS 2013 和更早版本
當 或 UNICODE_STRING 結構的 ANSI_STRING 位址當做引數傳遞時,顯示結構欄位所 Buffer 指向之緩衝區中包含的字串。 使用 的大小 修飾詞前置 w 詞來指定 UNICODE_STRING 引數, %wZ 例如 。 該結構的 Length 欄位必須設定為此字串的長度,以位元組為單位。 該結構的 MaximumLength 欄位必須設定為此緩衝區的長度,以位元組為單位。

通用 C 執行時間 (UCRT)
目前為了相容性而維護的 UCRT 有一個已知問題。 S如同規範, Z 沒有大小修飾詞前置詞的規範是指 UNICODE_STRING 使用窄型列印函式時 (例如 printf ) 和 ANSI_STRING 使用寬列印函式時 (例如 ) wprintf 的 。
使用 來 Z 指定 ANSI_STRINGhZ 而不是 。 wZ (或 lZ )仍然可以用來指定 UNICODE_STRING

一般而言, Z 類型字元只會用於使用轉換規格的驅動程式偵錯函式,例如 dbgPrintkdPrint

在 Visual Studio 2015 和更新版本中,如果對應至浮點轉換規範的引數(、、、、、 fGgFE ) 是無限、無限或 NaN,則格式化的輸出符合 C99 標準。 eAa 下表列出格式化輸出︰

輸出
Infinity inf
無訊息 NaN nan
訊號 NaN nan(snan)
不確定的 NAN nan(ind)

這些字串中任何一個可能前面都會加上符號。 如果浮點 type 轉換規範字元是大寫字母,則輸出的格式也是以大寫字母呈現。 例如,如果格式規範是 %F 而不是 %f,則無限值會格式化為 INF 而不是 infscanf 函式也可剖析這些字串,因此這些值可以往返 printfscanf 函式。

在 Visual Studio 2015 之前,CRT 對無限大、不確定及 NAN 值的輸出使用不同的非標準格式︰

輸出
+ 無限大 1.#INF隨機數字
-無限 -1.#INF隨機數字
不確定 (與無訊息的 NaN 相同) 數字.#IND隨機數字
NaN 數字.#NAN隨機數字

這些字串中任何一個可能前面都有符號,而且可能根據欄位寬度和精確度而以不同的方式格式化,有時會有不尋常的效果。 例如, printf("%.2f\n", INFINITY) 列印 1.#J ,因為 #INF 會「四捨五入」到兩位數的有效位數。

注意

如果對應到 %s%S 的引數或是對應到 %Z 的引數之 Buffer 欄位為 null 指標,則會顯示 "(null)"。

注意

在所有指數格式中,要顯示之指數的最小位數為二,僅在必要時使用三個位數。 藉由使用 函 _set_output_format 式,您可以將顯示的位數設定為 3,以便與針對 Visual Studio 2013 和之前撰寫的程式碼回溯相容性。

重要

%n因為格式原本就不安全,所以預設為停用。 如果在 %n 格式字串中遇到 ,則會叫用不正確參數處理常式,如參數驗證 中所述 。 若要啟用 %n 支援,請參閱 _set_printf_count_output

旗標指示詞

轉換規格中的第一個選擇性欄位包含 旗標指示詞 。 此欄位包含零個或多個旗標字元,可指定符號、空白、前置零、小數點和八進位和十六進位前置詞的輸出對齊和控制輸出。 轉換規格中可能會出現多個旗標指示詞,而旗標字元可按照任何順序出現。

旗標字元

旗標 意義 預設
- 靠左對齊給定欄位寬度內的結果。 靠右對齊。
+ 如果是帶正負號的類型,請使用符號 (+ 或 -) 作為輸出值前置詞。 僅為帶負號 (-) 的值顯示符號。
0 如果 寬度 前面加上 0 ,則會新增前置零,直到達到最小寬度為止。 如果 和 -0 出現, 0 則會忽略 。 如果 0 指定整數格式 ( ioXxdu 和 有效位數規格也存在 ,例如, %04.d0 則會忽略 。 如果 0a 或 浮點格式指定,則前置零會在 或 A0X 前置詞後面 0x 加上 mantissa。 無填補。
blank (' ') 如果輸出值已帶正負號且為正數,請使用空白作為前置詞。 如果空白字元及 + 旗標同時出現,則會略過空白字元。 不會出現空白字元。
# 與 、 x 或 格式搭配 o 使用時, # 旗標會分別使用 00xX0X ,來前置任何非零輸出值。 沒有出現前置詞。
當它搭配 eEfFaA 格式使用時, # 旗標會強制輸出值包含小數點。 小數點只有在後面有數字時才會顯示。
搭配 或 G 格式使用 g 時, # 旗標會強制輸出值包含小數點,並防止截斷尾端零。

與 、、 duis 搭配 c 使用時忽略。
小數點只有在後面有數字時才會顯示。 行尾零會被截斷。

寬度規格

在轉換規格中,選擇性寬度規格欄位會在任何 flags 字元後面出現。 自 width 變數是非負數十進位整數,可控制輸出的字元數下限。 如果輸出值中的字元數小於指定的寬度,空白字元會新增至值的左邊或右邊,取決於是否已指定靠左對齊的旗標 (-),直到達到最小寬度為止。 如果 width 前面加上 0,則前置零會加入整數或浮點轉換,直到達到最小寬度為止,除非轉換為無限大或 NaN

寬度規格一律不會截斷值。 如果輸出值中的字元數大於指定的寬度,或 width 未提供,則值的所有字元都會輸出,但受限於有效位數規格。

如果寬度規格是星號 (*),來自引數清單的 int 引數就會提供值。 自 width 變數必須位於引數清單中格式化的值之前,如下列範例所示:

printf("%0*d", 5, 3); /* 00003 is output */

轉換規格中的遺漏或小型 width 值不會造成輸出值的截斷。 如果轉換的結果大於 width 值,欄位會展開以包含轉換結果。

精確度規格

在轉換規格中,第三個選擇性欄位是精確度規格。 它是由句號 ( . ) 所組成,後面接著非負數的十進位整數,視轉換類型而定,會指定字串字元數目、小數位數或要輸出的有效位數。

不同於寬度規格,精確度規格會造成輸出值截斷或浮點數值四捨五入。 如果 precision 指定為 0,且要轉換的值是 0,則結果不會輸出字元,如下列範例所示:

printf( "%.0d", 0 ); /* No characters output */

如果精確度規格是星號 (*),來自引數清單的 int 引數就會提供值。 在引數清單中,precision 引數的前面必須加上已格式化的值,如下例所示︰

printf( "%.*f", 3, 3.14159265 ); /* 3.142 output */

type當省略 時 precision ,字元會決定的解譯 precision 或預設有效位數,如下表所示。

有效位數值如何影響類型

類型 意義 預設
a, A 指定小數點之後位數的精確度。 預設精確度為 13。 如果精確度為 0,除非使用 # 旗標,否則不會列印小數點。
c, C 精確度無效果。 列印字元。
d, i, o, u, x, X 精確度指定要列印的最小位數。 如果引數中的位數小於 precision,輸出值左邊以零填補。 當位數超過 有效位數 時,不會截斷此值。 預設精確度為 1。
e, E 精確度指定小數點後要列印的位數。 最後一個列印數字已四捨五入。 預設精確度為 6。 如果 有效位數 為 0 或句號 ( . ) 未顯示之後的數位,則不會列印小數點。
f, F 精確度值指定小數點後的位數。 如果出現小數點,它的前面至少要出現一個數字。 值會四捨五入到適當的位數。 預設精確度為 6。 如果 有效位數 為 0,或者句號 ( . ) 在之後沒有數位出現,則不會列印小數點。
g, G 精確度指定列印的最大有效位數。 列印六個有效位數,並截斷任何結尾的零。
s, S 精確度指定要列印的最大字元數。 不列印超過 precision 的字元。 字元會列印到找到 Null 字元為止。

引數大小規格

在轉換規格中,size欄位是 type 轉換規範的引數長度修飾詞。 大小欄位會前置詞到 類型 欄位— hhhlj (小寫 L)、 tllL 、、、 zwI (大寫 i)、 I32I64 —指定對應的引數「size」,也就是 long 或 short、32 位或 64 位、單位元組字元或寬字元,視修改的轉換規範而定。 這些大小前置詞可在 printfwprintf 系列函式中搭配 type 字元使用,以指定引數大小的轉譯,如下表所示。 size 對於某些引數類型是選擇性欄位。 未指定大小前置詞時,格式子會使用整數引數 (例如帶正負號或不帶正負號的 charshortintlong 和列舉類型) 作為 32 位元 int 類型,並使用 floatdoublelong double 浮點引數作為 64 位元 double 類型。 這個行為符合變數引數清單的預設引數提升規則。 如需引數升級的詳細資訊,請參閱後置運算式 中的 省略號和預設引數。 在 32 位和 64 位系統上,64 位整數引數的轉換規格必須包含 或 I64 的大小前置詞 ll 。 否則,格式子的行為未定義。

某些類型在 32 位元和 64 位元程式碼中的大小不同。 例如,size_t 在針對 x86 所編譯的程式碼中的長度為 32 位元,在針對 x64 所編譯的程式碼中的長度為 64 位元。 若要針對變動寬度類型建立無從驗證平台的格式化程式碼,您可以使用變動寬度的引數大小修飾詞。 請改用 64 位引數大小修飾詞,並將變數寬度引數類型明確提升為 64 位。 Microsoft 特定的 I (大寫 i) 引數大小修飾詞會處理變數寬度的整數引數,但我們建議使用特定類型 jtz 修飾詞,以便可攜性。

printf 和 wprintf 格式類型規範的大小前置詞

若要指定 使用前置詞 類型規範為
char
unsigned char
hh diouxX
short int
short unsigned int
h diouxX
__int32
unsigned __int32
I32 diouxX
__int64
unsigned __int64
I64 diouxX
intmax_t
uintmax_t
jI64 diouxX
long double l (小寫 L) 或 L aAeEfFgG
long int
long unsigned int
l (小寫 L) diouxX
long long int
unsigned long long int
ll (小寫 LL) diouxX
ptrdiff_t tI (大寫 i) diouxX
size_t zI (大寫 i) diouxX
單一位元組字元 h cC
寬字元 l (小寫 L) 或 w cC
單一位元組字元字串 h sSZ
寬字元字串 l (小寫 L) 或 w sSZ

ptrdiff_tsize_t 類型在 32 位元平台上為 __int32unsigned __int32,而在 64 位元平台上則為 __int64unsigned __int64I(大寫 i)、、 jtz 大小前置詞會針對平臺採用正確的引數寬度。

在 Visual C++ 中,雖然 long double類型不同,但具有相同的內部表示法 double

hchC 型別規範與 函式和 C 函式中的 wprintfprintf 同義 c 字。 、 、 或 型別規範與 C 函式和 c 函式中的 printfwprintf 同義字。 wCwclClc hshS 型別規範與 函式和 S 函式中的 wprintfprintf 同義 s 字。 、 、 或 型別規範與 S 函式和 s 函式中的 printfwprintf 同義字。 wSwslSls

注意

Microsoft 特定:
I(大寫 i)、、 I32I64w 引數大小修飾詞前置詞是 Microsoft 延伸模組,且與 ISO C 不相容。 當 h 前置詞搭配類型資料使用時,前置詞與類型 chardouble 資料類型搭配使用時,則 l 為 (小寫 L) 前置詞為 Microsoft 延伸模組。

另請參閱

printf, _printf_l, wprintf, _wprintf_l
printf_s, _printf_s_l, wprintf_s, _wprintf_s_l
printf_p 位置參數