c文件輸出函數printf, fprintf, sprintf, snprintf, printf_s, fprintf_s, sprintf_s, snprintf_s

轉自:https://zh.cppreference.com/w/c/io/fprintf

 

定義於頭文件 <stdio.h>

   
  (1)  

int printf( const char *format, ... );

(C99 前)

int printf( const char *restrict format, ... );

(C99 起)
  (2)  

int fprintf( FILE *stream, const char *format, ... );

(C99 前)

int fprintf( FILE *restrict stream, const char *restrict format, ... );

(C99 起)
  (3)  

int sprintf( char *buffer, const char *format, ... );

(C99 前)

int sprintf( char *restrict buffer, const char *restrict format, ... );

(C99 起)

int snprintf( char *restrict buffer, int bufsz, 
              const char *restrict format, ... );

(4) (C99 起)

int printf_s(const char *restrict format, ...);

(5) (C11 起)

int fprintf_s(FILE *restrict stream, const char *restrict format, ...);

(6) (C11 起)

int sprintf_s(char *restrict buffer, rsize_t bufsz,
              const char *restrict format, ...);

(7) (C11 起)

int snprintf_s(char *restrict buffer, rsize_t bufsz,
               const char *restrict format, ...);

(8) (C11 起)
     

從給定位置加載數據,轉換爲字符串等價物,並寫結果到各種池。

1) 寫結果到 stdout 。

2) 寫結果到文件流 stream 。

3) 寫結果到字符串 buffer 。

4) 寫結果到字符串 buffer 。至多寫 buf_size - 1 個字符。產生的字符串會以空字符終止,除非 buf_size 爲零。若 buf_size 爲零,則不寫入任何內容,且 buffer 可以是空指針,然而依舊計算返回值(會寫入的字符數,不包含空終止符)並返回。

5-8) 同 (1-4) ,除了在運行時檢測下列錯誤,並調用當前安裝的制約處理函數:

  • format 中存在轉換指定符 %n
  • 任何一個對應 %s 的參數是空指針
  • format 或 buffer 是空指針
  • bufsz 爲零或大於 RSIZE_MAX
  • 在任何一個字符串及字符轉換指定符中出現編碼錯誤
  • (僅對於 sprintf_s )存儲於 buffer 的字符串(包括尾隨空字符)長度將超出 bufsz

同所有邊界檢查函數, printf_s, fprintf_s, sprintf_s, snrintf_s 僅若實現定義了 __STDC_LIB_EXT1__ ,且用戶在包含 <stdio.h> 前定義 __STDC_WANT_LIB_EXT1__ 爲整數常量 1 才保證可用。

參數

stream - 要寫入的輸出文件流
buffer - 指向要寫入的字符串的指針
bufsz - 最多會寫入 bufsz - 1 個字符,再加空終止符
format - 指向指定數據轉譯方式的空終止多字節字符串的指針。

格式字符串由普通多字節字符(除了 % )和轉換指定構成,前者被複制到輸出流而無更改。每個轉換指定擁有下列格式:

  • 引入的 % 字符
  • (可選)一或多個修改轉換行爲的標籤:
  • - :轉換結果在域內左校正(默認爲右校正)
  • + :有符號轉換的符號始終前置於轉換結果(默認結果前置負號僅當它爲負)
  • 空格:若有符號轉換的結果不以符號開始,或爲空,則前置空格於結果。若存在 + 標籤則忽略空格
  • # :進行另一種形式的轉換。準確的效果見下表,其他情況下行爲未定義。
  • 0 :對於整數和浮點數轉換,使用前導零代替空格字符填充域。對於整數,若顯式指定精度,則忽略此標籤。對於其他轉換,使用此標籤導致未定義行爲。若存在 - 標籤則忽略 0 。
  • (可選)指定最小域寬的整數值或 * 。若有要求,則結果會以空格字符(默認情況)填充,在右校正時於左,左校正時於右。使用 * 的情況下,以一個額外的 int 類型參數指定寬度。若參數值爲負數,則它導致指定 - 標籤和正域寬。(注意:這是最小寬度:決不被截斷值)。
  • (可選)後隨整數或 * 或兩者皆無的 . 指示轉換的精度。在使用 * 的情況下,精度由額外的 int 類型參數指定。若此參數的值爲負數,則它被忽略。若既不使用數字亦不使用 * ,則精度採用零。精度的準確效果見下表。
  • (可選)指定參數大小的長度修飾符
  • 轉換格式指定符

下列格式指定符可用:

轉換
指定符
解釋 參數類型
長度修飾符 hh

(C99)

h (無) l ll

(C99)

j

(C99)

z

(C99)

t

(C99)

L
% 寫字面的 % 。完整轉換指定必須是 %% 。 N/A N/A N/A N/A N/A N/A N/A N/A N/A
c

單個字符

參數首先被轉換成 unsigned char 。 若使用 l 修飾符,則參數首先被轉換成字符串,如同通過以 wchar_t[2] 參數使用 %ls 。

N/A N/A

int

wint_t

N/A N/A N/A N/A N/A
s

寫一個字符串

參數必須是指向字符數組首元素的指針 精度指定寫入最大的字符數。若未指定精度,則寫每個字節直到而而不含首個空終止符。 若使用 l 指定符,則參數必須是指向 wchar_t 數組首元素的指針,數組會被轉換成 char 數組,如同通過以零初始化轉換狀態調用 wcrtomb 。

N/A N/A

char*

wchar_t*

N/A N/A N/A N/A N/A
d
i

轉換一個有符號整數爲十進制表示 [-]dddd 。

精度指定出現的最小數位數。默認精度是 1 。
若被轉換的值和精度都是  0  ,則轉換結果無字符。

signed char

short

int

long

long long

intmax_t

有符號 size_t

ptrdiff_t

N/A
o

轉換一個無符號整數爲八進制表示 oooo 。

精度指定出現的最小數位數。默認精度是 1 。 若被轉換值和精度都是  0  ,則轉換結果無字符。 在另一種實現中精度按需增加,以寫入一個前導零。 在此情況下若被轉換值和精度都是  0  ,則寫入單個  0  。

unsigned char

unsigned short

unsigned int

unsigned long

unsigned long long

uintmax_t

size_t

ptrdiff_t 的無符號版本

N/A
x
X

轉換一個無符號整數爲十六進制表示 hhhh 。

x 轉換使用字母 abcdef 。
X 轉換使用 ABCDEF 。
精度指定出現的最小數位數。默認精度是 1 。 若被轉換值和精度都是  0  ,則轉換結果無字符。 在另一種實現中若被轉換值爲非零則結果有 0x 或 0X 前綴。

N/A
u

轉換一個無符號整數爲十進制表示 dddd 。

精度指定出現的最小數位數。 默認精度是 1 。 若被轉換值和精度都是  0  ,則轉換結果無字符。

N/A
f
F

轉換一個浮點數爲 [-]ddd.ddd 樣式的十進制記法。

精度指定小數點字符後出現的最小數位數。 默認精度是 6 。 在另一種實現中即使沒有小數點後數位也寫小數點。 無窮大和非數的轉換樣式見注意。

N/A N/A

double

double (C99)

N/A N/A N/A N/A

long double

e 
E

轉換一個浮點數爲十進制指數記法。

e 轉換樣式使用 [-]d.ddde±dd 。
E 轉換樣式使用 [-]d.dddE±dd 。
指數至少含二個數位,僅當所需時使用更多數位。 若值爲  0  ,則指數亦爲  0  。 精度指定小數點字符後出現的最小數位數。 默認精度是 6 。 在另一種實現中即使沒有小數點後數位也寫小數點。 無窮大和非數的轉換樣式見注意。

N/A N/A N/A N/A N/A N/A
a 
A

(C99)

轉換一個浮點數爲十六進制記法。

a 轉換樣式使用 [-]0xh.hhhp±d 。
A 轉換樣式使用 [-]0Xh.hhhP±d 。
若參數不是正規化的浮點值,則首個十六進制數位爲 0。 若值爲  0  ,則指數亦爲  0  。 精度指定小數點字符後出現的最小數位數。 默認精度足以準確表示該值。 在另一種實現中即使沒有小數點後數位也寫小數點。 無窮大和非數的轉換樣式見注意。

N/A N/A N/A N/A N/A N/A
g 
G

轉換一個浮點數爲十進制小數或十進制指數記法,依賴於值和精度

g 轉換樣式將進行帶樣式 e 或 f 的轉換。
G 轉換樣式將進行帶樣式 E 或 F 的轉換。
令 P 等於精度,若它非零,若精度未指定則爲 6 ,若精度爲  0  則等於 1 。然後,若帶樣式 E 的轉換會有指數 X ,則:

  • 若 P > X ≥ −4 ,則轉換帶 f 或 F 風格,及精度 P − 1 − X 。
  • 否則,轉換帶 e 或 E 風格,及精度 P − 1 。

除非要求另一種表示,否則末尾零會被移除,且若不留下小數部分則小數點亦被移除。 無窮大和非數的轉換樣式見注意。

N/A N/A N/A N/A N/A N/A
n

返回對函數的此調用迄今爲止寫入的字符數

結果被寫入到參數所指向的值。 該指定不可含有任何標籤域寬精度

signed char*

short*

int*

long*

long long*

intmax_t*

有符號 size_t*

ptrdiff_t*

N/A
p 寫定義一個指針的實現定義字符序列。 N/A N/A void* N/A N/A N/A N/A N/A N/A

浮點轉換函數轉換無窮大到 inf 或 infinity 。使用哪一個是實現定義的。

非數轉換成 nan 或 nan(char_sequence) 。使用哪一個是實現定義的。

轉換 F 、 E 、 G 、 A 替代上面輸出 INF 、 INFINITY 、 NAN

儘管 %c 期待 int 參數,傳遞 char 是安全的,因爲在調用變參數函數時發生整數提升。

定寬整數類型( int8_t 等)的正確轉換指定定義於頭文件 <inttypes.h> (儘管 PRIdMAX 、 PRIuMAX 等就是 %jd、 %ju 等的別名)。

內存寫入轉換指定符 %n 是安全漏洞的常見目標,這裏格式字符串依賴用戶輸入,而此轉換指定符不爲邊界檢查的 printf_s 系列函數所支持。

在每個轉換指定符的行動後有一個序列點;這允許存入多次 %n 的結果於同一變量,並在同一調用中打印出先前以 %n 存儲的值。

若轉換指定非法,則行爲未定義。

 

... - 指定要打印數據的參數。若任何默認參數提升後的參數不擁有對應轉換指定符所期待的類型,或若參數數量少於 format 的要求,則行爲未定義。若有多於 format 要求的參數,則求值並忽略多出的參數。

返回值

1,2) 傳輸到輸出流的字符數,或若出現輸出錯誤或編碼錯誤(對於字符串和字符轉換指定符)則爲負值。

3) 寫入到 buffer 的字符數(不計空終止字符),或若輸出錯誤或編碼錯誤(對於字符串和字符轉換指定符)發生則爲負值。

4) 假如忽略 bufsz 則本應寫入到 buffer 的字符數(不計空終止字符),或若出現輸出錯誤或編碼錯誤(對於字符串和字符轉換指定符)則爲負值。

5,6) 傳輸到輸出流的字符數,或若出現輸出錯誤、運行時制約違規錯誤或編碼錯誤則爲負值。

7) 寫入到buffer的字符數,不計空終止字符(只要 buffer 不是空指針且 bufsz 非零且不大於 RSIZE_MAX ,就寫入它),在運行時制約違規時爲零,而在編碼錯誤時爲負值。

8) 假如忽略 bufsz 則本應寫入 buffer 的字符數的,不包含空終止字符(只要 buffer 不是空指針而 bufsz 非零且不大於 RSIZE_MAX ,就寫入它),或若出現輸出錯誤、運行時制約違規錯誤或編碼錯誤則爲負值。

注意

C 標準及POSIX 指定 sprintf 及其變體的行爲在參數與目標緩衝區重疊時未定義。示例:

sprintf(dst, "%s and %s", dst, t); // <- 有錯:未定義行爲

POSIX指定在錯誤時設置errno。它亦指定附加的轉換指定,最值得注意的是對參數重排序的支持(緊隨%之後的n$指示第n個參數)。

以零爲 bufsz 和空指針爲 buffer 調用 snprintf 可用於決定包含輸出的緩衝區大小:

const char *fmt = "sqrt(2) = %f";
int sz = snprintf(NULL, 0, fmt, sqrt(2));
char buf[sz + 1]; // 注意爲終止空字符 +1
snprintf(buf, sizeof buf, fmt, sqrt(2));

同 snprintf ,但不同於 sprintf_s , snprintf_s 會將輸出截斷在 bufsz-1 之內。

示例

運行此代碼

#include <stdio.h>
 
int main(void)
{
    printf("Strings:\n");
    const char* s = "Hello";
    printf("\t.%10s.\n\t.%-10s.\n\t.%*s.\n", s, s, 10, s);
 
    printf("Characters:\t%c %%\n", 65);
 
    printf("Integers\n");
    printf("Decimal:\t%i %d %.6i %i %.0i %+i %u\n", 1, 2, 3, 0, 0, 4, -1);
    printf("Hexadecimal:\t%x %x %X %#x\n", 5, 10, 10, 6);
    printf("Octal:\t%o %#o %#o\n", 10, 10, 4);
 
    printf("Floating point\n");
    printf("Rounding:\t%f %.0f %.32f\n", 1.5, 1.5, 1.3);
    printf("Padding:\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
    printf("Scientific:\t%E %e\n", 1.5, 1.5);
    printf("Hexadecimal:\t%a %A\n", 1.5, 1.5);
}

輸出:

Strings:
    .     Hello.
    .Hello     .
    .     Hello.
Characters:     A %
Integers
Decimal:        1 2 000003 0  +4 4294967295
Hexadecimal:    5 a A 0x6
Octal:          12 012 04
Floating point
Rounding:       1.500000 2 1.30000000000000004440892098500626
Padding:        01.50 1.50  1.50
Scientific:     1.500000E+00 1.500000e+00
Hexadecimal:    0x1.8p+0 0X1.8P+0

引用

  • C11 standard (ISO/IEC 9899:2011):
  • 7.21.6.1 The fprintf function (p: 309-316)
  • 7.21.6.3 The printf function (p: 324)
  • 7.21.6.5 The snprintf function (p: 325)
  • 7.21.6.6 The sprintf function (p: 325-326)
  • K.3.5.3.1 The fprintf_s function (p: 591)
  • K.3.5.3.3 The printf_s function (p: 593-594)
  • K.3.5.3.5 The snprintf_s function (p: 594-595)
  • K.3.5.3.6 The sprintf_s function (p: 595-596)
  • C99 standard (ISO/IEC 9899:1999):
  • 7.19.6.1 The fprintf function (p: 274-282)
  • 7.19.6.3 The printf function (p: 290)
  • 7.19.6.5 The snprintf function (p: 290-291)
  • 7.19.6.6 The sprintf function (p: 291)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 4.9.6.1 The fprintf function
  • 4.9.6.3 The printf function
  • 4.9.6.5 The sprintf function

參閱

wprintf
fwprintf
swprintf
wprintf_s
fwprintf_s
swprintf_s
snwprintf_s

(C95)
(C95)
(C95)
(C11)
(C11)
(C11)
(C11)

打印格式化寬字符輸出到stdout、文件流或緩衝區 
(函數)

vprintf
vfprintf
vsprintf
vsnprintf
vprintf_s
vfprintf_s
vsprintf_s
vsnprintf_s




(C99)
(C11)
(C11)
(C11)
(C11)

打印格式化輸出到stdout、文件流或緩衝區
使用可變參數列表 
(函數)

fputs

將一個字符串寫入文件流 
(函數)

scanf
fscanf
sscanf
scanf_s
fscanf_s
sscanf_s




(C11)
(C11)
(C11)

stdin、文件流或緩衝區讀取格式化輸入 
(函數)

printf, fprintf, sprintf, snprintf 的 C++ 文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章