格式規格語法: printf
和 wprintf
函式
各種 printf
與 wprintf
函式皆會採用格式字串和選擇性引數,然後產生格式化的輸出字元序列。 格式字串包含零或多個「指示詞」,這是輸出的常值字元或是編碼的「轉換規格」,其會說明如何將輸出的引數格式化。 本文說明格式字串中用來為轉換規格進行編碼的語法。 如需這些函式的清單,請參閱資料流 I/O。
轉換規格包含選擇性及必要欄位,形式如下︰
每個轉換規格的欄位都是字元,或是表示特定格式選項或轉換規範的數字。 必要的 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
來指定c
s
S
單一位元組和多位元組或寬字元字串,視所使用的格式化函式而定。 使用 c
和所指定的字元和字串自變數會解譯為printf
char*
char
和依系列函式,或依系列函式來解譯為 wchar_t
和。s
wchar_t*
wprintf
使用 C
和所指定的字元和字串自變數會解譯為printf
wchar_t*
wchar_t
和依系列函式,或依系列函式來解譯為 char
和。S
char*
wprintf
此行為Microsoft特定。 基於歷史原因,函wprintf
式會使用 c
和 s
來參考wchar_t
字元,並C
S
指定窄字元。
整數型別,例如 short
、int
、、long long
long
、 及其unsigned
變體,是使用 d
、i
、o
、、u
、 x
和 X
來指定。 使用、e
A
、double
long double
、、f
E
、 g
F
和 G
等float
浮點類型來a
指定。 根據預設,除非它們是由 大小 前置詞修改,否則整數自變數會強制 int
型別,而浮點自變數則會強制設定為 double
。 在 64 位系統上,int
是 32 位值;因此,除非使用 或 I64
的大小前置ll
詞,否則 64 位整數會在格式化輸出時截斷。 使用平台的預設指標大小所 p
指定的指標類型。
注意
Microsoft 專有:
與 Z
和 wprintf
函式搭配printf
使用、、 s
和 S
型別字元時,類型字元和的行為c
C
Microsoft擴充功能。 ISO C 標準會針對c
窄字元和字串使用和s
一致的方式,以及S
C
所有格式化函式中的寬字元和字串。
類型欄位字元
類型字元 | Argument | 輸出格式 |
---|---|---|
c |
字元 | 搭配 printf 函式使用時,會指定單一位元組字元;搭配 wprintf 函式使用時,會指定寬字元。 |
C |
字元 | 搭配 printf 函式使用時,會指定寬字元;搭配 wprintf 函式使用時,會指定單一位元組字元。 |
d |
整數 | 帶正負號的十進位整數。 |
i |
整數 | 帶正負號的十進位整數。 |
o |
整數 | 不帶正負號的八進位整數。 |
u |
整數 | 不帶正負號的十進位整數。 |
x |
整數 | 不帶正負號的十六進位整數;使用 “abcdef ”。 |
X |
整數 | 不帶正負號的十六進位整數;使用 “ABCDEF ”。 |
e |
浮點 | 具有格式為 [- ]d.dde []dd[dd[+ |- d]的帶正負號值,其中 d 是一個十進位數,dddd 是一或多個十進制數,視指定的有效位數或預設為 6,dd[d] 是兩或三個十進位數,視指數的輸出格式和大小而定。 |
E |
浮點 | 與 e 格式相同,不同之處在於 E ,而不是 e 引進指數。 |
f |
浮點 | 帶正負號的值,其格式為 [- ]d. d,其中 dd 是一或多個十進位數。 小數點前面的位數取決於數字的大小,小數點後面的位數則取決於要求的精確度,或是預設為六。 |
F |
浮點 | 與 f 格式相同,不同之處在於無限大和 NaN 輸出會大寫。 |
g |
浮點 | 帶正負號的值會以 f 或 e 格式顯示,無論哪個值和精確度都比較精簡。 e 只有當值的指數小於 -4 或大於或等於 precision 自變數時,才會使用格式。 會截斷尾端的零,僅當一或多個數字位於小數點後面時,才會顯示小數點。 |
G |
浮點 | 與 g 格式相同,不同之處在於 E ,而不是 e ,會介紹指數(若適當)。 |
a |
浮點 | 帶正負號的十六進位雙精確度浮點值,其格式為 [- ]0x h.hhhhp [- + |]dd,其中 h.hhhhh 是 mantissa 的十六進位數位(使用小寫字母),而 dd 是指數的一或多個數位。 指定小數點之後位數的精確度。 |
A |
浮點 | 帶正負號的十六進位雙精確度浮點值,其格式為 [- ]0X h.hhhhP [- + |]dd,其中 h.hhhhh 是 mantissa 的十六進位數位(使用大寫字母),而 dd 是指數的一或多個數位。 指定小數點之後位數的精確度。 |
n |
整數的指標 | 目前已成功寫入此資料流或緩衝區的字元數。 會將這個值儲存在整數中,該整數的位址會做為引數而受指定。 引數大小規格前置詞可以控制指向整數的大小。 n 指定名稱預設會停用;如需資訊,請參閱重要安全性注意事項。 |
p |
指標類型 | 以十六進位數字顯示自變數作為位址。 |
s |
String | 當搭配 printf 函式使用時,會指定單一位元組或多位元組字元字串;當搭配 wprintf 函式使用時,會指定寬字元字串。 字元會顯示,直到第一個 null 字元或達到 precision 值為止。 |
S |
String | 當搭配 printf 函式使用時,會指定寬字元字串;當搭配 wprintf 函式使用時,會指定單一位元組或多位元組字元字串。 字元會顯示,直到第一個 null 字元或達到 precision 值為止。 |
Z |
ANSI_STRING 或 UNICODE_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_STRING ,hZ 而不是 。 wZ (或 lZ )仍然可以用來指定 UNICODE_STRING 。 一般而言, Z 類型字元只會用於使用轉換規格的驅動程式偵錯函式,例如 dbgPrint 和 kdPrint 。 |
在 Visual Studio 2015 和更新版本中,如果對應至浮點轉換規範的自變數(、、、、、 f
G
F
E
g
) 是無限、無限或 NaN,則格式化的輸出符合 C99 標準。 e
A
a
下表列出格式化輸出︰
值 | 輸出 |
---|---|
Infinity | inf |
無訊息 NaN | nan |
訊號 NaN | nan(snan) |
不確定的 NAN | nan(ind) |
這些字串中任何一個可能前面都會加上符號。 如果浮點 type 轉換規範字元是大寫字母,則輸出的格式也是以大寫字母呈現。 例如,如果格式規範是 %F
而不是 %f
,則無限值會格式化為 INF
而不是 inf
。 scanf
函式也可剖析這些字串,因此這些值可以往返 printf
和 scanf
函式。
在 Visual Studio 2015 之前,CRT 對無限大、不確定及 NAN 值的輸出使用不同的非標準格式︰
值 | 輸出 |
---|---|
+ 無限大 | 1.#INF random-digits |
-無限 | -1.#INF random-digits |
不確定 (與無訊息的 NaN 相同) | digit .#IND random-digits |
NaN | digit .#NAN random-digits |
這些字串中任何一個可能前面都有符號,而且可能根據字段寬度和精確度而以不同的方式格式化,有時會有不尋常的效果。 例如, 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 指定整數格式 (i 、 o d x u X 與有效位數規格也存在 ,例如,%04.d 0 則會忽略 。 如果 0 為 a 或 浮點格式指定,則前置零會在 或 A 0X 前置詞後面0x 加上 mantissa。 |
無填補。 |
blank (' ') | 如果輸出值已帶正負號且為正數,請使用空白作為前置詞。 如果空白字元及 + 旗標同時出現,則會略過空白字元。 | 不會出現空白字元。 |
# |
與 、 x 或 格式搭配o 使用時,# 旗標會分別使用 0 、 0x 或 X 0X ,來前置任何非零輸出值。 |
沒有出現前置詞。 |
當它搭配 e 、 E 、 f 、 F 、 a 或 A 格式使用時, # 旗標會強制輸出值包含小數點。 |
小數點只有在後面有數字時才會顯示。 | |
搭配 或 G 格式使用g 時,# 旗標會強制輸出值包含小數點,並防止截斷尾端零。與 、、 d 、 u i 或 s 搭配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 轉換規範的引數長度修飾詞。 大小欄位會前置詞到類型欄位—hh
、h
、 l
j
(小寫 L)、t
L
ll
、、、I
z
w
(大寫 i)、I32
和 I64
—指定對應的自變數“size”,也就是 long 或 short、32 位或 64 位、單位元組位元或寬字元,視修改的轉換規範而定。 這些大小前置詞可在 printf
和 wprintf
系列函式中搭配 type 字元使用,以指定引數大小的轉譯,如下表所示。 size 對於某些引數類型是選擇性欄位。 未指定大小前置詞時,格式子會使用整數引數 (例如帶正負號或不帶正負號的 char
、short
、int
、long
和列舉類型) 作為 32 位元 int
類型,並使用 float
、double
及 long double
浮點引數作為 64 位元 double
類型。 這個行為符合變數引數清單的預設引數提升規則。 如需自變數升級的詳細資訊,請參閱後置表達式中的省略號和預設自變數。 在 32 位和 64 位系統上,64 位整數自變數的轉換規格必須包含 或I64
的大小前置詞ll
。 否則,格式子的行為未定義。
某些類型在 32 位元和 64 位元程式碼中的大小不同。 例如,size_t
在針對 x86 所編譯的程式碼中的長度為 32 位元,在針對 x64 所編譯的程式碼中的長度為 64 位元。 若要針對變動寬度類型建立無從驗證平台的格式化程式碼,您可以使用變動寬度的引數大小修飾詞。 請改用 64 位自變數大小修飾詞,並將變數寬度自變數類型明確提升為 64 位。 Microsoft特定 I
(大寫 i) 自變數大小修飾詞會處理變數寬度的整數自變數,但我們建議類型特定的 j
、 t
和 z
修飾詞,以便可移植性。
printf 和 wprintf 格式類型規範的大小前置詞
若要指定 | 使用前置詞 | 類型規範為 |
---|---|---|
char unsigned char |
hh |
d 、i 、o 、u 、x 或 X |
short int short unsigned int |
h |
d 、i 、o 、u 、x 或 X |
__int32 unsigned __int32 |
I32 |
d 、i 、o 、u 、x 或 X |
__int64 unsigned __int64 |
I64 |
d 、i 、o 、u 、x 或 X |
intmax_t uintmax_t |
j 或 I64 |
d 、i 、o 、u 、x 或 X |
long double |
l (小寫 L) 或 L |
a 、A 、e 、E 、f 、F 、g 或 G |
long int long unsigned int |
l (小寫 L) |
d 、i 、o 、u 、x 或 X |
long long int unsigned long long int |
ll (小寫 LL) |
d 、i 、o 、u 、x 或 X |
ptrdiff_t |
t 或 I (大寫 i) |
d 、i 、o 、u 、x 或 X |
size_t |
z 或 I (大寫 i) |
d 、i 、o 、u 、x 或 X |
單一位元組字元 | h |
c 或 C |
寬字元 | l (小寫 L) 或 w |
c 或 C |
單一位元組字元字串 | h |
s 、 S 或 Z |
寬字元字串 | l (小寫 L) 或 w |
s 、 S 或 Z |
ptrdiff_t
與 size_t
類型在 32 位元平台上為 __int32
或 unsigned __int32
,而在 64 位元平台上則為 __int64
或 unsigned __int64
。 I
(大寫 i)、、 j
t
和 z
大小前置詞會針對平台採用正確的自變數寬度。
在 Visual C++ 中,雖然 long double
類型不同,但具有相同的內部表示法 double
。
hc
或 hC
型別規範與函式和 C
函式中的 wprintf
printf
同義c
字。 、 或 型別規範與 C
函式和 c
函式中的 printf
wprintf
同義字。wC
wc
lC
lc
hs
或 hS
型別規範與函式和 S
函式中的 wprintf
printf
同義s
字。 、 或 型別規範與S
函式和 s
函式中的 printf
wprintf
同義字。wS
ws
lS
ls
注意
Microsoft 專有:
I
(大寫 i)、、 I32
I64
和 w
自變數大小修飾詞前置詞是Microsoft延伸模組,且與 ISO C 不相容。 當h
前置詞與 類型的數據搭配使用時,當它搭配型char
別double
的數據使用時,前置l
詞是Microsoft延伸模組。
另請參閱
printf
、 、 _printf_l
、 wprintf
_wprintf_l
printf_s
、 、 _printf_s_l
、 wprintf_s
_wprintf_s_l
printf_p
位置參數