湖南網(wǎng)站制作公司湖南seo網(wǎng)站策劃
標準IO
標準 I/O 雖然是對文件 I/O 進行了封裝,但事實上并不僅僅只是如此,標準 I/O 會處理很多細節(jié),譬如分配 stdio 緩沖區(qū)、以優(yōu)化的塊長度執(zhí)行 I/O 等,這些處理使用戶不必擔心如何選擇使用正確的塊長度。I/O 庫函數(shù)是構建于文件 I/O(open()、 read()、 write()、 lseek()、 close()等)這些系統(tǒng)調用之上的,譬如標準 I/O 庫函數(shù) fopen()就利用系統(tǒng)調用 open()來執(zhí)行打開文件的操作、 fread()利用系統(tǒng)調用 read()來執(zhí)行讀文件操作、 fwrite()則利用系統(tǒng)調用 write()來執(zhí)行寫文件操作等等。那既然如此,為何還需要設計標準 I/O 庫?直接使用文件 I/O 系統(tǒng)調用不是更好嗎?事實上,并非如此, 在第一章中我們也提到過,設計庫函數(shù)是為了提供比底層系統(tǒng)調用更為方便、好用的調用接口, 雖然標準 I/O 構建于文件 I/O 之上, 但標準 I/O 卻有它自己的優(yōu)勢,標準 I/O 和文件 I/O 的區(qū)別如下:
雖然標準 I/O 和文件 I/O 都是 C 語言函數(shù),但是標準 I/O 是標準 C 庫函數(shù),而文件 I/O 則是 Linux系統(tǒng)調用;
標準 I/O 是由文件 I/O 封裝而來,標準 I/O 內部實際上是調用文件 I/O 來完成實際操作的;
-
可移植性:標準 I/O 相比于文件 I/O 具有更好的可移植性,通常對于不同的操作系統(tǒng),其內核向應用層提供的系統(tǒng)調用往往都是不同,譬如系統(tǒng)調用的定義、功能、參數(shù)列表、返回值等往往都是不一樣的;而對于標準 I/O 來說,由于很多操作系統(tǒng)都實現(xiàn)了標準 I/O 庫,標準 I/O 庫在不同的操作系統(tǒng)之間其接口定義幾乎是一樣的,所以標準 I/O 在不同操作系統(tǒng)之間相比于文件 I/O 具有更好的可移植性。
-
性能、效率: 標準 I/O 庫在用戶空間維護了自己的 stdio 緩沖區(qū), 所以標準 I/O 是帶有緩存的,而文件 I/O 在用戶空間是不帶有緩存的,所以在性能、效率上,標準 I/O 要優(yōu)于文件 I/O。
對于標準 I/O 庫函數(shù)來說,它們的操作是圍繞 FILE 指針進行的,當使用標準 I/O 庫函數(shù)打開或創(chuàng)建一個文件時,會返回一個指向 FILE 類型對象的指針(FILE *) ,使用該 FILE 指針與被打開或創(chuàng)建的文件相關聯(lián),然后該 FILE 指針就用于后續(xù)的標準 I/O 操作(使用標準 I/O 庫函數(shù)進行 I/O 操作),所以由此可知,FILE 指針的作用相當于文件描述符,只不過 FILE 指針用于標準 I/O 庫函數(shù)中、而文件描述符則用于文件I/O 系統(tǒng)調用中。FILE 是一個結構體數(shù)據(jù)類型,它包含了標準 I/O 庫函數(shù)為管理文件所需要的所有信息,包括用于實際I/O 的文件描述符、指向文件緩沖區(qū)的指針、緩沖區(qū)的長度、當前緩沖區(qū)中的字節(jié)數(shù)以及出錯標志等。 FILE數(shù)據(jù)結構定義在標準 I/O 庫函數(shù)頭文件 stdio.h 中。
所謂標準輸入設備指的就是計算機系統(tǒng)的標準的輸入設備,通常指的是計算機所連接的鍵盤;而標準輸出設備指的是計算機系統(tǒng)中用于輸出標準信息的設備,通常指的是計算機所連接的顯示器;標準錯誤設備則指的是計算機系統(tǒng)中用于顯示錯誤信息的設備,通常也指的是顯示器設備。
用戶通過標準輸入設備與系統(tǒng)進行交互, 進程將從標準輸入(stdin)文件中得到輸入數(shù)據(jù),將正常輸出數(shù)據(jù)(譬如程序中 printf 打印輸出的字符串) 輸出到標準輸出(stdout) 文件,而將錯誤信息(譬如函數(shù)調用報錯打印的信息)輸出到標準錯誤(stderr) 文件。標準輸出文件和標準錯誤文件都對應終端的屏幕,而標準輸入文件則對應于鍵盤。每個進程啟動之后都會默認打開標準輸入、標準輸出以及標準錯誤, 得到三個文件描述符, 即 0、 1、2, 其中 0 代表標準輸入、 1 代表標準輸出、 2 代表標準錯誤;
在應用編程中可以使用宏 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO 分別代表 0、 1、 2,這些宏定義在 unistd.h 頭文件中:
/* Standard file descriptors. */ #define STDIN_FILENO 0 /* Standard input. */ #define STDOUT_FILENO1 /* Standard output. */ #define STDERR_FILENO2 /* Standard error output. */
0、 1、 2 這三個是文件描述符,只能用于文件 I/O(read()、 write()等),那么在標準 I/O 中,自然是無法使用文件描述符來對文件進行 I/O 操作的,它們需要圍繞 FILE 類型指針來進行,在 stdio.h 頭文件中有相應的定義,如下:
/* Standard streams. */ extern struct _IO_FILE *stdin; /* Standard input stream. */ extern struct _IO_FILE *stdout; /* Standard output stream. */ extern struct _IO_FILE *stderr; /* Standard error output stream. */ /* C89/C99 say they're macros. Make them happy. */ #define stdin stdin #define stdout stdou t#define stderr stderr
Tips: struct _IO_FILE 結構體就是 FILE 結構體,使用了 typedef 進行了重命名。所以,在標準 I/O 中,可以使用 stdin、 stdout、 stderr 來表示標準輸入、標準輸出和標準錯誤。
用庫函數(shù)fopen()打開或創(chuàng)建文件, fopen()函數(shù)原型如下所示:
#include <stdio.h> FILE *fopen(const char *path, const char *mode);
使用該函數(shù)需要包含頭文件 stdio.h。函數(shù)參數(shù)和返回值含義如下:
-
path: 參數(shù) path 指向文件路徑,可以是絕對路徑、也可以是相對路徑。
-
mode: 參數(shù) mode 指定了對該文件的讀寫權限,是一個字符串,稍后介紹。
-
返回值: 調用成功返回一個指向 FILE 類型對象的指針(FILE *),該指針與打開或創(chuàng)建的文件相關聯(lián),后續(xù)的標準 I/O 操作將圍繞 FILE 指針進行。 如果失敗則返回 NULL,并設置 errno 以指示錯誤原因。參數(shù) mode 字符串類型,可取值為如下值之一:
mode | 說明 | flags 參數(shù)取值 |
---|---|---|
r | 以只讀方式打開文件。 | O_RDONLY |
r+ | 以可讀、可寫方式打開文件。 | O_RDWR |
w | 以只寫方式打開文件;如果文件存在,將文件長度截斷為0;如果文件不存在,則創(chuàng)建文件。 | O_WRONLY | O_CREAT | O_TRUNC |
w+ | 以可讀、可寫方式打開文件;如果文件存在,將文件長度截斷為0;如果文件不存在,則創(chuàng)建文件。 | O_RDWR |O_CREAT O_TRUNC |
a | 以只寫方式打開文件,進行追加內容(在文件末尾寫入);如果文件不存在,則創(chuàng)建文件。 | O_WRONLY | O_CREAT | O_APPEND |
a+ | 以可讀、可寫方式打開文件,進行追加內容(在文件末尾寫入);如果文件不存在,則創(chuàng)建文件。 | O_RDWR | O_CREAT | O_APPEND |
讀文件和寫文件
當使用 fopen()庫函數(shù)打開文件之后,接著我們便可以使用 fread()和 fwrite()庫函數(shù)對文件進行讀、寫操作了,函數(shù)原型如下所示:
#include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
庫函數(shù) fread()用于讀取文件數(shù)據(jù),其參數(shù)和返回值含義如下:
-
ptr: fread()將讀取到的數(shù)據(jù)存放在參數(shù) ptr 指向的緩沖區(qū)中;
-
size: fread()從文件讀取 nmemb 個數(shù)據(jù)項,每一個數(shù)據(jù)項的大小為 size 個字節(jié),所以總共讀取的數(shù)據(jù)大小為 nmemb * size 個字節(jié)。
-
nmemb: 參數(shù) nmemb 指定了讀取數(shù)據(jù)項的個數(shù)。stream: FILE 指針。
-
返回值: 調用成功時返回讀取到的數(shù)據(jù)項的數(shù)目(數(shù)據(jù)項數(shù)目并不等于實際讀取的字節(jié)數(shù),除非參數(shù)size 等于 1);如果發(fā)生錯誤或到達文件末尾,則 fread()返回的值將小于參數(shù) nmemb,那么到底發(fā)生了錯誤還是到達了文件末尾, fread()不能區(qū)分文件結尾和錯誤, 究竟是哪一種情況,此時可以使用 ferror()或 feof()函數(shù)來判斷
庫函數(shù) fwrite()用于將數(shù)據(jù)寫入到文件中,其參數(shù)和返回值含義如下:
-
ptr: 將參數(shù) ptr 指向的緩沖區(qū)中的數(shù)據(jù)寫入到文件中。
-
size: 參數(shù) size 指定了每個數(shù)據(jù)項的字節(jié)大小,與 fread()函數(shù)的 size 參數(shù)意義相同。
-
nmemb: 參數(shù) nmemb 指定了寫入的數(shù)據(jù)項個數(shù),與 fread()函數(shù)的 nmemb 參數(shù)意義相同。stream: FILE 指針。
-
返回值: 調用成功時返回寫入的數(shù)據(jù)項的數(shù)目(數(shù)據(jù)項數(shù)目并不等于實際寫入的字節(jié)數(shù),除非參數(shù) size等于 1);如果發(fā)生錯誤,則 fwrite()返回的值將小于參數(shù) nmemb(或者等于 0)。
由此可知,庫函數(shù) fread()、 fwrite()中指定讀取或寫入數(shù)據(jù)大小的方式與系統(tǒng)調用 read()、 write()不同,前者通過 nmemb(數(shù)據(jù)項個數(shù)) *size(每個數(shù)據(jù)項的大小)的方式來指定數(shù)據(jù)大小,而后者則直接通過一個 size 參數(shù)指定數(shù)據(jù)大小。譬如要將一個 struct mystr 結構體數(shù)據(jù)寫入到文件中:
-
可按如下方式寫入:fwrite(buf, sizeof(struct mystr), 1, file);
-
當然也可以按如下方式寫:fwrite(buf, 1, sizeof(struct mystr), file);
庫函數(shù) fseek()的作用類似于系統(tǒng)調用 lseek(), 用于設置文件讀寫位置偏移量, lseek()用于文件 I/O,而庫函數(shù) fseek()則用于標準 I/O,其函數(shù)原型如下所示:
#include <stdio.h>int fseek(FILE *stream, long offset, int whence);
函數(shù)參數(shù)和返回值含義如下:
-
stream: FILE 指針。
-
offset: 與 lseek()函數(shù)的 offset 參數(shù)意義相同。
-
whence: 與 lseek()函數(shù)的 whence 參數(shù)意義相同。
-
返回值: 成功返回 0;發(fā)生錯誤將返回-1,并且會設置 errno 以指示錯誤原因; 與 lseek()函數(shù)的返回值意義不同,這里要注意!調用庫函數(shù) fread()、 fwrite()讀寫文件時,文件的讀寫位置偏移量會自動遞增,使用 fseek()可手動設置文件當前的讀寫位置偏移量。
-
譬如將文件的讀寫位置移動到文件開頭處:fseek(file, 0, SEEK_SET);
-
將文件的讀寫位置移動到文件末尾:fseek(file, 0, SEEK_END);
-
將文件的讀寫位置移動到 100 個字節(jié)偏移量處:fseek(file, 100, SEEK_SET);
調用 fread()讀取數(shù)據(jù)時,如果返回值小于參數(shù) nmemb 所指定的值,表示發(fā)生了錯誤或者已經到了文件末尾(文件結束 end-of-file),但 fread()無法具體確定是哪一種情況; 在這種情況下,可以通過判斷錯誤標志或 end-of-file 標志來確定具體的情況。feof()函數(shù)庫函數(shù) feof()用于測試參數(shù) stream 所指文件的 end-of-file 標志,如果 end-of-file 標志被設置了,則調用feof()函數(shù)將返回一個非零值,如果 end-of-file 標志沒有被設置,則返回 0。
#include <stdio.h> int feof(FILE *stream);
當文件的讀寫位置移動到了文件末尾時, end-of-file 標志將會被設置。庫函數(shù) ferror()用于測試參數(shù) stream 所指文件的錯誤標志,如果錯誤標志被設置了,則調用 ferror()函數(shù)將返回一個非零值,如果錯誤標志沒有被設置,則返回 0。其函數(shù)原型如下所示:
#include <stdio.h> int ferror(FILE *stream);
C 庫函數(shù)提供了 5 個格式化輸出函數(shù),包括: printf()、 fprintf()、 dprintf()、 sprintf()、 snprintf(),其函數(shù)定義如下所示:
#include <stdio.h> int printf(const char *format, ...); int fprintf(FILE *stream, const char *format, ...); int dprintf(int fd, const char *format, ...); int sprintf(char *buf, const char *format, ...); int snprintf(char *buf, size_t size, const char *format, ...);
這 5 個函數(shù)都是可變參函數(shù),它們都有一個共同的參數(shù) format,這是一個字符串,稱為格式控制字符串,用于指定后續(xù)的參數(shù)如何進行格式轉換, 所以才把這些函數(shù)稱為格式化輸出,因為它們可以以調用者指定的格式進行轉換輸出; 學習這些函數(shù)的重點就是掌握這個格式控制字符串 format 的書寫格式以及它們所代表的意義, 每個函數(shù)除了固定參數(shù)之外,還可攜帶 0 個或多個可變參數(shù)。printf()函數(shù)
用于將格式化數(shù)據(jù)寫入到標準輸出; dprintf()和 fprintf()函數(shù)用于將格式化數(shù)據(jù)寫入到指定的文件中,兩者不同之處在于, fprintf()使用 FILE 指針指定對應的文件、而 dprintf()則使用文件描述符 fd 指定對應的文件; sprintf()、 snprintf()函數(shù)可將格式化的數(shù)據(jù)存儲在用戶指定的緩沖區(qū) buf 中。printf()函數(shù)前面章節(jié)內容編寫的示例代碼中多次使用了該函數(shù),用于將程序中的字符串信息輸出顯示到終端(也就是標準輸出),它是一個可變參函數(shù),除了一個固定參數(shù) format外,后面還可攜帶 0 個或多個參數(shù)。函數(shù)調用成功返回打印輸出的字符數(shù);失敗將返回一個負值!打印“Hello World”:printf("Hello World!\n");打印數(shù)字 5:printf("%d\n", 5);
fprintf()可將格式化數(shù)據(jù)寫入到由 FILE 指針指定的文件中,譬如將字符串“Hello World”寫入到標準錯誤:fprintf(stderr, "Hello World!\n");向標準錯誤寫入數(shù)字 5:fprintf(stderr, "%d\n", 5);函數(shù)調用成功返回寫入到文件中的字符數(shù);失敗將返回一個負值!
dprintf()可將格式化數(shù)據(jù)寫入到由文件描述符 fd 指定的文件中,譬如將字符串“Hello World”寫入到標準錯誤:dprintf(STDERR_FILENO, "Hello World!\n");向標準錯誤寫入數(shù)字 5:dprintf(STDERR_FILENO, "%d\n", 5);函數(shù)調用成功返回寫入到文件中的字符數(shù);失敗將返回一個負值!
sprintf()函數(shù):sprintf()函數(shù)將格式化數(shù)據(jù)存儲在由參數(shù) buf 所指定的緩沖區(qū)中, 譬如將字符串“Hello World”存放在緩沖區(qū)中:
char buf[100];sprintf(buf, "Hello World!\n");
當然這種用法并沒有意義,事實上,我們一般會使用這個函數(shù)進行格式化轉換,并將轉換后的字符串存放在緩沖區(qū)中,譬如將數(shù)字 100 轉換為字符串"100",將轉換后得到的字符串存放在 buf 中:
char buf[20] = {0}; sprintf(buf, "%d", 100);
sprintf()函數(shù)會在字符串尾端自動加上一個字符串終止字符'\0'。
需要注意的是, sprintf()函數(shù)可能會造成由參數(shù) buf 指定的緩沖區(qū)溢出,調用者有責任確保該緩沖區(qū)足夠大,因為緩沖區(qū)溢出會造成程序不穩(wěn)定甚至安全隱患!函數(shù)調用成功返回寫入到 buf 中的字節(jié)數(shù);失敗將返回一個負值!snprintf()函數(shù)sprintf()函數(shù)可能會發(fā)生緩沖區(qū)溢出的問題,存在安全隱患,為了解決這個問題,引入了 snprintf()函數(shù);在該函數(shù)中,使用參數(shù) size 顯式的指定緩沖區(qū)的大小,如果寫入到緩沖區(qū)的字節(jié)數(shù)大于參數(shù) size 指定的大小,超出的部分將會被丟棄!如果緩沖區(qū)空間足夠大, snprintf()函數(shù)就會返回寫入到緩沖區(qū)的字符數(shù),與sprintf()函數(shù)相同,也會在字符串末尾自動添加終止字符'\0'。若發(fā)生錯誤, snprintf()將返回一個負值!
以上 5 個函數(shù)中的 format 參數(shù)應該怎么寫,把這個參數(shù)稱為格式控制字符串,顧名思義,首先它是一個字符串的形式,其次它能夠控制后續(xù)變參的格式轉換。格式控制字符串由兩部分組成:普通字符(非%字符) 和轉換說明。普通字符會進行原樣輸出,每個轉換說明都會對應后續(xù)的一個參數(shù),通常有幾個轉換說明就需要提供幾個參數(shù)(除固定參數(shù)之外的參數(shù)), 使之一一對應,用于控制對應的參數(shù)如何進行轉換。如下所示:printf("轉換說明 1 轉換說明 2 轉換說明 3", arg1, arg2, arg3);這里只是以 printf()函數(shù)舉個例子,實際上并不這樣用。三個轉換說明與參數(shù)進行一一對應,按照順序方式一一對應。每個轉換說明都是以%字符開頭,其格式如下所示(使用[ ]括起來的部分是可選的) :
%[flags][width][.precision][length]type
-
flags: 標志,可包含 0 個或多個標志;
-
width: 輸出最小寬度,表示轉換后輸出字符串的最小寬度;precision: 精度,前面有一個點號" . ";
-
length: 長度修飾符;
-
type: 轉換類型,指定待轉換數(shù)據(jù)的類型。
-
可以看到,只有%和 type 字段是必須的,其余都是可選的。
首先說明 type(類型), 因為類型是格式控制字符串的重中之重,是必不可少的組成部分,其它的字段都是可選的, type 用于指定輸出數(shù)據(jù)的類型, type 字段使用一個字符(字母字符)來表示:
字符 | 對應數(shù)據(jù)類型 | 含義 | 示例說明 |
---|---|---|---|
d/i | int | 輸出有符號十進制表示的整數(shù),i 是老式寫法 | printf("%d\n", 123); 輸出: 123 |
o | unsigned int | 輸出無符號八進制表示的整數(shù)(默認不輸出前綴0,可在 # 標志下輸出前綴0) | printf("%o\n", 123); 輸出: 173 |
u | unsigned int | 輸出無符號十進制表示的整數(shù) | printf("%u\n", 123); 輸出: 123 |
x/X | unsigned int | 輸出無符號十六進制表示的整數(shù),x 和 X 區(qū)別在于字母大小寫 | printf("%x\n", 123); 輸出: 7b printf("%X\n", 123); 輸出: 7B |
f/F | double | 輸出浮點數(shù),f 和 F 區(qū)別在于字母大小寫,默認保留小數(shù)點后 6 位數(shù) | printf("%f\n", 520.1314); 輸出: 520.131400 printf("%F\n", 520.1314); 輸出: 520.131400 |
e/E | double | 輸出以科學計數(shù)法表示的浮點數(shù),e 和 E 區(qū)別在于字母大小寫 | printf("%e\n", 520.1314); 輸出: 5.201314e+02 printf("%E\n", 520.1314); 輸出: 5.201314E+02 |
g | double | 根據(jù)數(shù)值的長度,選擇以最短方式輸出,%f/%e | printf("%g %g\n", 0.000000123, 0.123); 輸出: 1.23e-07 0.123 |
G | double | 根據(jù)數(shù)值的長度,選擇以最短方式輸出,%F/%E | printf("%G %G\n", 0.000000123, 0.123); 輸出: 1.23E-07 0.123 |
s | char * | 字符串,輸出字符串中的字符直到終止字符 \0 | printf("%s\n", "Hello World"); 輸出: Hello World |
p | void * | 輸出十六進制表示的指針 | printf("%p\n", "Hello World"); 輸出: 0x400624 |
c | char | 字符型,將輸入的數(shù)字轉換為對應的 ASCII 字符輸出 | printf("%c\n", 64); 輸出: A |
flags字段的含義如下:
字符 | 名稱 | 作用 |
---|---|---|
# | 井號 | 對于 o 類型,輸出字符串增加前綴 0;對于 x 或 X 類型,輸出前綴 0x 或 0X 。對于浮點數(shù)類型,強制輸出小數(shù)點。 |
0 | 數(shù)字 0 | 當輸出數(shù)字(非 c 或 s 類型)時,在輸出前補 0,直到達到指定最小寬度。 |
- | 減號 | 左對齊輸出,若寬度不足則在右邊填充空格。若同時指定 0 和 - ,- 會覆蓋 0 。 |
' ' | 空格 | 輸出正數(shù)時,在數(shù)字前加一個空格,負數(shù)則加負號 - 。 |
+ | 加號 | 輸出時無論正數(shù)還是負數(shù),前面都帶符號。正數(shù)帶 + ,負數(shù)帶 - 。+ 會覆蓋 ' ' (空格)。 |
寬度類型 | 描述 | 示例 |
---|---|---|
數(shù)字 | 指定輸出的最小寬度,若實際輸出位數(shù)小于指定寬度,前面會補充空格或 0 。 | printf("%06d", 1000); 輸出: 001000 |
* | 不顯示寬度數(shù)值,寬度由參數(shù)列表中的值指定。 | printf("%0*d", 6, 1000); 輸出: 001000 |
描述 | 類型 | 示例 |
---|---|---|
數(shù)字 | 整型(d , i , o , u , x , X ) | 對于整型,指定輸出的最小數(shù)字位數(shù),不足時補前導零。 例如 printf("%8.5d", 100); 輸出: 00100 |
浮點型(a , A , e , E , f , F ) | 對于浮點數(shù),指定小數(shù)點后數(shù)字的個數(shù)。默認6位。 例如 printf("%.8f", 520.1314); 輸出: 520.13140000 | |
g , G | 對于 g 和 G ,表示最大有效數(shù)字位數(shù)。 | |
字符串 | s | 指定最大輸出字符數(shù),超過則截斷。 例如 printf("%.5s", "hello world"); 輸出: hello |
* | 星號 | 精度由參數(shù)列表指定,例如 printf("%.*s", 5, "hello world"); 輸出: hello |
長度修飾符指明待轉換數(shù)據(jù)的長度,因為 type 字段指定的的類型只有 int、unsigned int 以及 double 等幾種數(shù)據(jù)類型,但是C 語言內置的數(shù)據(jù)類型不止這幾種,譬如有 16bit 的 short、unsigned short,8bit 的char、unsigned char,也有64bit 的 long long 等,為了能夠區(qū)別不同長度的數(shù)據(jù)類型,于是乎,長度修飾符(length)應運而生,成為轉換說明的一部分。 length 長度修飾符也是使用字符(字母字符)來表示,結合type 字段以確定不同長度的數(shù)據(jù)類型:
type | length | 描述 |
---|---|---|
d , i | none | int 類型,輸出有符號十進制整數(shù)。 |
u , o , x , X | none | unsigned int 類型,輸出無符號十進制、八進制、十六進制整數(shù)。 |
f , F , e , E , g , G | none | double 類型,輸出浮點數(shù),使用小數(shù)表示或科學計數(shù)法。 |
c | none | char 類型,輸出一個字符。 |
s | none | char * 類型,輸出字符串。 |
p | none | void * 類型,輸出指針的十六進制表示。 |
hh | signed char , unsigned char | signed char 或 unsigned char 類型,輸出字符。 |
h | short int , unsigned short int | short int 或 unsigned short int 類型,輸出整數(shù)。 |
l | long int , unsigned long int | long int 或 unsigned long int 類型,輸出整數(shù)。 |
wint_t | wchar_t | 寬字符類型(wint_t 或 wchar_t ),用于寬字符處理。 |
ll | long long int , unsigned long long int | long long int 或 unsigned long long int 類型,輸出整數(shù)。 |
L | long double | long double 類型,輸出浮點數(shù)。 |
j | intmax_t , uintmax_t | intmax_t 或 uintmax_t 類型,輸出整數(shù)。 |
z | size_t , ssize_t | size_t 或 ssize_t 類型,輸出無符號或有符號整數(shù)。 |
t | ptrdiff_t | ptrdiff_t 類型,表示指針差值。 |
格式化輸入是類似的,這里不加以贅述了。