【背景】
今天這個主要說的是<stdio.h>頭文件,大家眾所周知,這個是我們學習C語言時第一個接觸到的頭文件了,那么為什么我不一開始就介紹這個頭文件呢?我覺得有兩個原因,如下:
1.一開始大家的編程思想以及函數思維還不是很成熟,就像剛拿了駕照的同志,肯定不建議一個人上高速的,因為存在著諸多的不安全因素,那么,在我們這里不安全因素可以理解為函數思維和理解深度,一開始就研究這個頭文件,我敢說絕對理解的不深刻,而且會走很多彎路,為什么呢?因為這個頭文件好多都是關于文件指針的操作,而且函數多達42個,所以不管從學習還是理解程度來講,一開始就搞這個,肯定不是明智之選,那么經過我們學習了<math.h> <stdlib.h> <time.h> <limits.h>? <float.h> <string.h> <ctype.h> <assert.h> <stdarg.h> <setjmp.h>? <signal.h>這些頭文件,那么就對函數有一定的了解,函數思維和編程思維就熟悉了很多,那么再回頭來學習<stdio.h>就比較可以了,個人理解而已,也因人而異,反正我是這么覺著的哦
2.這個<stdio.h>的函數是比較多的,而且多半都是關于文件指針的操作,所以對于指針的素養是有一定的要求的哦,還就是操作字符串,這個也是個基礎,因為寫文件讀文件等都是關于字符串的操作,沒有這個基礎,就比較糾結了哦
綜上所述便是我個人的理解,所以我們言歸正傳,開始學習<stdio.h>頭文件
【前言】
stdio .h?頭文件定義了三個變量類型、一些宏和各種函數來執行輸入和輸出。
庫變量
下面是頭文件 stdio.h 中定義的變量類型:
序號 | 變量 & 描述 |
---|---|
1 | size_t 這是無符號整數類型,它是?sizeof?關鍵字的結果。 |
2 | FILE 這是一個適合存儲文件流信息的對象類型。 |
3 | fpos_t 這是一個適合存儲文件中任何位置的對象類型。 |
庫宏
下面是頭文件 stdio.h 中定義的宏:
序號 | 宏 & 描述 |
---|---|
1 | NULL 這個宏是一個空指針常量的值。 |
2 | _IOFBF、_IOLBF?和?_IONBF 這些宏擴展了帶有特定值的整型常量表達式,并適用于?setvbuf?函數的第三個參數。 |
3 | BUFSIZ 這個宏是一個整數,該整數代表了?setbuf?函數使用的緩沖區大小。 |
4 | EOF 這個宏是一個表示已經到達文件結束的負整數。 |
5 | FOPEN_MAX 這個宏是一個整數,該整數代表了系統可以同時打開的文件數量。 |
6 | FILENAME_MAX 這個宏是一個整數,該整數代表了字符數組可以存儲的文件名的最大長度。如果實現沒有任何限制,則該值應為推薦的最大值。 |
7 | L_tmpnam 這個宏是一個整數,該整數代表了字符數組可以存儲的由 tmpnam 函數創建的臨時文件名的最大長度。 |
8 | SEEK_CUR、SEEK_END?和?SEEK_SET 這些宏是在?fseek?函數中使用,用于在一個文件中定位不同的位置。 |
9 | TMP_MAX 這個宏是 tmpnam 函數可生成的獨特文件名的最大數量。 |
10 | stderr、stdin?和?stdout 這些宏是指向 FILE 類型的指針,分別對應于標準錯誤、標準輸入和標準輸出流。 |
這些知識點請熟悉,我們會在后面的代碼中使用
【函數1:fopen】
【格式】
FILE *fopen(const char *filename, const char *mode)
【功能】
使用給定的模式 mode 打開 filename 所指向的文件
【入參】
const char *filename:字符串,表示要打開的文件名稱
const char *mode:字符串,表示文件的訪問模式,可以是以下表格中的值
模式 | 描述 |
---|---|
"r" | 打開一個用于讀取的文件。該文件必須存在。 |
"w" | 創建一個用于寫入的空文件。如果文件名稱與已存在的文件相同,則會刪除已有文件的內容,文件被視為一個新的空文件。 |
"a" | 追加到一個文件。寫操作向文件末尾追加數據。如果文件不存在,則創建文件。 |
"r+" | 打開一個用于更新的文件,可讀取也可寫入。該文件必須存在。 |
"w+" | 創建一個用于讀寫的空文件。 |
"a+" | 打開一個用于讀取和追加的文件 |
注意 :關于filename常量,表示的是要打開的文件名稱,這里可以是名稱(比如:a.txt)也可以是一個路徑(比如:F:\A00_code_test_C\zll_debug_00\zll_debug.txt),還有一個細節要注意就是在windows系統下運行代碼的話,表示路徑的話要用雙斜杠(比如:F:\\A00_code_test_C\\zll_debug_00\\zll_debug.txt)
【返回值】
該函數返回一個 FILE 指針。否則返回 NULL,且設置全局變量 errno 來標識錯誤(這個會使文件指針fp會帶有錯誤標識符,這個具體有什么作用,請見clearerr函數講解)
【TestCode】
1.在當前目錄下創建a.txt文件并寫入數據
2.在當前目錄下創建zll_debug.txt文件并寫入數據
3.以讀的方式打開文件zll_debug.txt并輸出文件內容到終端
4.以追加的方式向zll_debug.txt寫入數據
【總結】
1.fopen函數的操作權限大家最好多練習練習,熟能生巧
2.關于testcode中的4.大家發現沒有:追加的數據是緊挨著文件中原有的數據的哦,那么如果要換行追加的話,怎么搞?換兩行呢?大家可以思考下
3.關于二進制文件的操作,這個一般操作的不多,除非在匯編里可能多點,還有就是驅動力可能有些,我們先不探討哦,這個會在linux c中到時候探討一下
【函數2:fclose】
【格式】
int fclose(FILE *stream)
【功能】
關閉流 stream。刷新所有的緩沖區
【入參】
FILE *stream:文件流指針,指向操作的文件
【返回值】
如果流成功關閉,則該方法返回零。如果失敗,則返回 EOF
【TestCode】
【總結】
1.切記fclose函數和fopen是成對出現的,也就是說只要你fopen了文件,就一定要fclose文件,不然的話,文件會損壞的哦
2.關于追加換行的問題,上述示例代碼已演示,這個是在windows下的哦
【函數3:clearerr】
【格式】
void clearerr(FILE *stream)
【功能】
清除給定流 stream 的文件結束和錯誤標識符
【入參】
FILE *stream:文件流指針,指向操作的文件
【返回值】
void類型,無返回值
【TestCode】
clearerr后
沒clearerr時
【總結】
clearerr是清除給定流 fp?的文件結束和錯誤標識符,這兩個標識符會在我們操作文件的時候,根據相應的情況,系統自動給賦值,所以我們操作文件的時候一定要安全的操作哦
【函數4:feof】
【格式】
int feof(FILE *stream)
【功能】
測試給定流 stream 的文件結束標識符
【入參】
FILE *stream:文件流指針,指向操作的文件
【返回值】
當設置了與流關聯的文件結束標識符時,該函數返回一個非零值,否則返回零
【TestCode】
【總結】
注意理解返回值這句話:當設置了與流關聯的文件結束標識符時,該函數返回一個非零值,否則返回零
這個意思是說當沒有讀到文件末尾的時候,feof函數并不會檢測到文件結束標識符,也就是說這個時候feof(fp)返回的值為0;當讀到文件末尾的時候,此時feof函數會檢測到fp的文件結束標識符(這個文件結束標識符是文件系統設置的),也就是說這個時候feof(fp)返回的值為非零
【函數5:ferror】
【格式】
int ferror(FILE *stream)
【功能】
測試給定流 stream 的錯誤標識符
【入參】
FILE *stream:文件流指針,指向操作的文件
【返回值】
如果設置了與流關聯的錯誤標識符,該函數返回一個非零值,否則返回一個零值
【TestCode】
【總結】
注意理解這個錯誤標識符,這個是對文件進行了錯誤的不恰當的操作后(如例子中是以只寫的方式打開文件的,卻在后面進行了讀操作),系統給設置的一個錯誤標識符,表明文件的一個當前狀態,ferror可以檢測到這個錯誤標識符的一個狀態
【函數6:setbuf】
【格式】
void setbuf(FILE *stream, char *buffer)
【功能】
定義流 stream 應如何緩沖。
該函數應在與流 stream 相關的文件被打開時,且還未發生任何輸入或輸出操作之前被調用一次
【入參】
FILE *stream:文件流指針,指向操作的流
char *buffer:這是分配給用戶的緩沖,它的長度至少為 BUFSIZ 字節,BUFSIZ 是一個宏常量,表示數組的長度
【返回值】
該函數不返回任何值
【TestCode】
【總結】
setbuf會向緩沖區str里puts數據,等到fflush刷新緩沖區的時候,就會將這些數據輸出到終端,那么,如果不刷新呢?如下:
如果不使用fflush進行刷新的話,會一直緩沖到緩沖區,直到使用完str緩沖區,就會生成亂碼并結束,圖中一行為30個字節,一共16行,總共480字節,加上最后一行大家可以算算,所以緩沖完后,記得刷新fflush哦
【函數7:fflush】
【格式】
int fflush(FILE *stream)
【功能】
刷新流 stream 的輸出緩沖區
【入參】
stream:?這是指向 FILE 對象的指針,該 FILE 對象指定了一個緩沖流
【返回值】
如果成功,該函數返回零值。如果發生錯誤,則返回 EOF,且設置錯誤標識符(即 feof)
【TestCode】
【總結】
大家有沒有發現,打印==end=zll_debug==并沒有打印出來,這說明了fflush調用后,直接就結束了?看實踐確實是這樣的,理論應該是如何的呢?這個待查明,留一個探討吧,自己接下里再看看,深究下再回復大家
【函數8:fgetpos】
【格式】
int fgetpos(FILE *stream, fpos_t *pos)
【功能】
獲取流 stream 的當前文件位置,并把它寫入到 pos
【入參】
FILE *stream: 這是指向 FILE 對象的指針,該 FILE 對象標識了流
fpos_t *pos: 這是指向 fpos_t 對象的指針
【返回值】
如果成功,該函數返回零。如果發生錯誤,則返回非零值
【TestCode】
【總結】
如上例子,fgetpos函數會獲取到文件的位置,不管你之前寫過什么,只要記住了這個位置,然后再用fsetpos函數將光標移動到這個位置后,再寫入的話,會覆蓋掉之前所有的寫入的哦。
【函數9:fread】
【格式】
size_t fread(void *ptr, size_t size, size_t count, FILE *stream)
【功能】
從給定流 stream 讀取數據到 ptr 所指向的數組中
【入參】
void *ptr:指向目的存儲塊,讀取到的內容放到這個內存里
?size_t size:單個元素的大小
?size_t count:所有元素的個數
?FILE *stream:讀的文件流
【返回值】
成功讀取的元素總數會以 size_t 對象返回,size_t 對象是一個整型數據類型。如果總數與 nmemb 參數不同,則可能發生了一個錯誤或者到達了文件末尾
【TestCode】
【總結】
在讀取文件的時候,一定要注意將文件的光標移動到文件的開始位置,不然的話,就會讀取不到內容,如下:
【函數10:freopen】
【格式】
FILE *freopen(const char *filename, const char *mode, FILE *stream)
【功能】
把一個新的文件名 filename 與給定的打開的流 stream 關聯,同時關閉流中的舊文件
【入參】
const char *filename:字符串,包含了要打開的文件名稱
?const char *mode:字符串,包含了文件訪問模式,模式如下:
模式 | 描述 |
---|---|
"r" | 打開一個用于讀取的文件。該文件必須存在。 |
"w" | 創建一個用于寫入的空文件。如果文件名稱與已存在的文件相同,則會刪除已有文件的內容,文件被視為一個新的空文件。 |
"a" | 追加到一個文件。寫操作向文件末尾追加數據。如果文件不存在,則創建文件。 |
"r+" | 打開一個用于更新的文件,可讀取也可寫入。該文件必須存在。 |
"w+" | 創建一個用于讀寫的空文件。 |
"a+" | 打開一個用于讀取和追加的文件。 |
?FILE *stream:這是指向 FILE 對象的指針,該 FILE 對象標識了要被重新打開的流
【返回值】
如果文件成功打開,則函數返回一個指針,指向用于標識流的對象。否則,返回空指針
【TestCode】
【總結】
發現沒?關聯后,輸出的內容直接就到zll_exec.txt文件里了,說實在的,這個功能真不清楚到底用在什么場合下,還是比較燒腦的,有大神的麻煩給說道說道?
【函數11:fseek】
【格式】
int fseek(FILE *stream, long int offset, int whence)
【功能】
設置流 stream 的文件位置為給定的偏移 offset,參數 offset 意味著從給定的 whence 位置查找的字節數
【入參】
FILE *stream:指向 FILE 對象的指針,該 FILE 對象標識了流
?long int offset:相對 whence 的偏移量,以字節為單位
?int whence:表示開始添加偏移 offset 的位置。它一般指定為下列常量之一:
常量 | 描述 |
---|---|
SEEK_SET | 文件的開頭 |
SEEK_CUR | 文件指針的當前位置 |
SEEK_END | 文件的末尾 |
【返回值】
如果成功,則該函數返回零,否則返回非零值。
【TestCode】
【總結】
實際fseek就是移動光標的函數,比如我們寫完文件后,要去讀我文件內容,最好將光標移動到文件開始位置,詳見fread函數舉例
【函數12:fsetpos】
【格式】
int fsetpos(FILE *stream, const fpos_t *pos)
【功能】
設置給定流 stream 的文件位置為給定的pos位置。參數 pos 是通過函數 fgetpos 獲取給定的位置。
【入參】
FILE *stream:文件流指針
const fpos_t *pos:指向 fpos_t 對象的指針,該對象包含了之前通過 fgetpos 獲得的位置
【返回值】
如果成功,該函數返回零值,否則返回非零值,并設置全局變量?errno?為一個正值,該值可通過 perror 來解釋
【TestCode】
【總結】
這個函數和fgetpos函數是成對使用的,個人覺得沒必要的情況下盡量別使用這個函數,容易導致文件光標或者文件內容紊亂,搞的最后自己都不知道pos在哪里了
【函數13:ftell】
【格式】
long int ftell(FILE *stream)
【功能】
返回給定流 stream 的當前文件光標位置
【入參】
FILE *stream:文件流指針
【返回值】
該函數返回位置標識符的當前值。如果發生錯誤,則返回 -1L,全局變量 errno 被設置為一個正值
【TestCode】
【總結】
根據個人理解,這個ftell說返回具體的光標(文件標識符)位置,會比較容易理解
【函數14:fwrite】
【格式】
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
【功能】
把 ptr 所指向的數組中的數據寫入到給定流 stream 中
【入參】
const void *ptr:待寫入的字符串內容
size_t size:寫入的總字符數
?size_t nmemb:單個字符,也就是單位量是多少(char = 1, int = 4...一般是sizeof(類型))
?FILE *stream:目標文件
【返回值】
如果成功,該函數返回一個 size_t 對象,表示元素的總數,該對象是一個整型數據類型。如果該數字與 nmemb 參數不同,則會顯示一個錯誤
【TestCode】
【總結】
這個寫入的時候注意,最好是通過sizeof去算多少和大小,盡量不要去手算,一個是別人不好讀,容易產生魔鬼數字,二是后期不好維護,好的代碼風格是大牛的基礎
【函數15:remove】
【格式】
int remove(const char *filename)
【功能】
刪除給定的文件名 filename,以便它不再被訪問(刪除文件)
【入參】
const char *filename:文件名
【返回值】
如果成功,則返回零。如果錯誤,則返回 -1,并設置 errno
【TestCode】
【總結】
1.注意為啥打開文件操作后關閉,再次進行remove會沒有作用?
經過debug后發現,是因為我使用fprintf函數是使用錯誤,應該如下使用:
2.注意路徑,是TT\\TP\\a.txt 這里是雙斜線哦
【函數16:rename】
【格式】
int rename(const char *old_filename, const char *new_filename)
【功能】
把 old_filename 所指向的文件名改為 new_filename
【入參】
const char *old_filename:老文件名
const char *new_filename:新文件名
【返回值】
如果成功,則返回零。如果錯誤,則返回 -1,并設置 errno
【TestCode】
【總結】
作用就是修改文件名,在修改的時候注意文件狀態,不能打開了去修改,如下:
【函數17:rewind】
【格式】
void rewind(FILE *stream)
【功能】
設置文件位置為給定流 stream 的文件的開頭
【入參】
FILE *stream:文件流
【返回值】
該函數不返回任何值
【TestCode】
【總結】
在操作完文件后,再去讀取內容的時候,一定要將光標移動到文件開始,不然可能讀取不到文件內容哦
【函數18:setbuf】
【格式】
void setbuf(FILE *stream, char *buffer)
【功能】
定義流 stream 應如何緩沖
【入參】
FILE *stream:文件流
?char *buffer:這是分配給用戶的緩沖,它的長度至少為 BUFSIZ (512)字節,BUFSIZ 是一個宏常量,表示數組的長度
【返回值】
無返回值
【TestCode】
【總結】
這個主要是緩沖到一定量后進行輸出,可以用fflush進行刷新輸出
【函數19:setvbuf】
【格式】
int setvbuf(FILE *stream, char *buffer, int mode, size_t size)
【功能】
另一個定義流 stream 應如何緩沖的函數
【入參】
FILE *stream:文件流指針
char *buffer:分配給用戶的緩沖。如果設置為 NULL,該函數會自動分配一個指定大小的緩沖
?int mode:模式
模式 | 描述 |
---|---|
_IOFBF | 全緩沖:對于輸出,數據在緩沖填滿時被一次性寫入。對于輸入,緩沖會在請求輸入且緩沖為空時被填充。 |
_IOLBF | 行緩沖:對于輸出,數據在遇到換行符或者在緩沖填滿時被寫入,具體視情況而定。對于輸入,緩沖會在請求輸入且緩沖為空時被填充,直到遇到下一個換行符。 |
_IONBF | 無緩沖:不使用緩沖。每個 I/O 操作都被即時寫入。buffer 和 size 參數被忽略。 |
?size_t size:這里是緩存的大小,也即是你要使用的buff大小
【返回值】
如果成功,則該函數返回 0,否則返回非零值
【TestCode】
【總結】
這個函數和setbuf函數類似,但是比它更精確些,一般也不經常使用,了解就行
【函數20:tmpfile】
【格式】
FILE *tmpfile(void)
【功能】
以二進制更新模式(wb+)創建臨時文件
【入參】
void:無入參
【返回值】
如果成功,該函數返回一個指向被創建的臨時文件的流指針。如果文件未被創建,則返回 NULL
【TestCode】
【總結】
具體也不清楚怎么用這個函數,還待深究了解
【函數21:tmpnam】
【格式】
char *tmpnam(char *str)
【功能】
生成并返回一個有效的臨時文件名,該文件名之前是不存在的
【入參】
char *str:臨時文件名
【返回值】
- 一個指向 C 字符串的指針,該字符串存儲了臨時文件名。如果 str 是一個空指針,則該指針指向一個內部緩沖區,緩沖區在下一次調用函數時被覆蓋。
- 如果 str 不是一個空指針,則返回 str。如果函數未能成功創建可用的文件名,則返回一個空指針
【TestCode】
【總結】
此函數使用時,入參str不能指定確定的名字哦,就算指定了系統也不會用,還會報錯,如下:
上面報錯是因為數組使用完了,定義大點,就不報錯,但是也沒用指定的名字,如下:
【函數22:fprintf】
【格式】
int fprintf(FILE *stream, const char *format, ...)
【功能】
發送格式化輸出到流 stream 中
【入參】
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了流。
- format?-- 這是 C 字符串,包含了要被寫入到流 stream 中的文本。它可以包含嵌入的 format 標簽,format 標簽可被隨后的附加參數中指定的值替換,并按需求進行格式化。format 標簽屬性是?%[flags][width][.precision][length]specifier,具體講解如下:
specifier(說明符) | 輸出 |
---|---|
c | 字符 |
d 或 i | 有符號十進制整數 |
e | 使用 e 字符的科學科學記數法(尾數和指數) |
E | 使用 E 字符的科學科學記數法(尾數和指數) |
f | 十進制浮點數 |
g | 自動選擇 %e 或 %f 中合適的表示法 |
G | 自動選擇 %E 或 %f 中合適的表示法 |
o | 有符號八進制 |
s | 字符的字符串 |
u | 無符號十進制整數 |
x | 無符號十六進制整數 |
X | 無符號十六進制整數(大寫字母) |
p | 指針地址 |
n | 無輸出 |
% | 字符 |
flags(標識) | 描述 |
---|---|
- | 在給定的字段寬度內左對齊,默認是右對齊(參見 width 子說明符)。 |
+ | 強制在結果之前顯示加號或減號(+ 或 -),即正數前面會顯示 + 號。默認情況下,只有負數前面會顯示一個 - 號。 |
(space) | 如果沒有寫入任何符號,則在該值前面插入一個空格。 |
# | 與 o、x 或 X 說明符一起使用時,非零值前面會分別顯示 0、0x 或 0X。 與 e、E 和 f 一起使用時,會強制輸出包含一個小數點,即使后邊沒有數字時也會顯示小數點。默認情況下,如果后邊沒有數字時候,不會顯示顯示小數點。 與 g 或 G 一起使用時,結果與使用 e 或 E 時相同,但是尾部的零不會被移除。 |
0 | 在指定填充 padding 的數字左邊放置零(0),而不是空格(參見 width 子說明符)。 |
width(寬度) | 描述 |
---|---|
(number) | 要輸出的字符的最小數目。如果輸出的值短于該數,結果會用空格填充。如果輸出的值長于該數,結果不會被截斷。 |
* | 寬度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
.precision(精度) | 描述 |
---|---|
.number | 對于整數說明符(d、i、o、u、x、X):precision 指定了要寫入的數字的最小位數。如果寫入的值短于該數,結果會用前導零來填充。如果寫入的值長于該數,結果不會被截斷。精度為 0 意味著不寫入任何字符。 對于 e、E 和 f 說明符:要在小數點后輸出的小數位數。 對于 g 和 G 說明符:要輸出的最大有效位數。 對于 s: 要輸出的最大字符數。默認情況下,所有字符都會被輸出,直到遇到末尾的空字符。 對于 c 類型:沒有任何影響。 當未指定任何精度時,默認為 1。如果指定時不帶有一個顯式值,則假定為 0。 |
.* | 精度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
length(長度) | 描述 |
---|---|
h | 參數被解釋為短整型或無符號短整型(僅適用于整數說明符:i、d、o、u、x 和 X)。 |
l | 參數被解釋為長整型或無符號長整型,適用于整數說明符(i、d、o、u、x 和 X)及說明符 c(表示一個寬字符)和 s(表示寬字符字符串)。 |
L | 參數被解釋為長雙精度型(僅適用于浮點數說明符:e、E、f、g 和 G)。 |
- 附加參數?-- 根據不同的 format 字符串,函數可能需要一系列的附加參數,每個參數包含了一個要被插入的值,替換了 format 參數中指定的每個 % 標簽。參數的個數應與 % 標簽的個數相同
【返回值】
如果成功,則返回寫入的字符總數,否則返回一個負數
【TestCode】
【總結】
根據不同的 format 字符串,函數可能需要一系列的附加參數,每個參數包含了一個要被插入的值,替換了 format 參數中指定的每個 % 標簽。參數的個數應與 % 標簽的個數相同
【函數23:printf】
【格式】
int printf(const char *format, ...)
【功能】
發送格式化輸出到標準輸出 stdout
printf("輸出格式",<參數表>);
【入參】
-
format?-- 這是字符串,包含了要被寫入到標準輸出 stdout 的文本。它可以包含嵌入的 format 標簽,format 標簽可被隨后的附加參數中指定的值替換,并按需求進行格式化。format 標簽屬性是?%[flags][width][.precision][length]specifier,具體講解如下:
格式字符 | 意義 |
---|---|
a, A | 以十六進制形式輸出浮點數(C99 新增)。 實例?printf("pi=%a\n", 3.14);?輸出?pi=0x1.91eb86p+1。 |
d | 以十進制形式輸出帶符號整數(正數不輸出符號) |
o | 以八進制形式輸出無符號整數(不輸出前綴0) |
x,X | 以十六進制形式輸出無符號整數(不輸出前綴Ox) |
u | 以十進制形式輸出無符號整數 |
f | 以小數形式輸出單、雙精度實數 |
e,E | 以指數形式輸出單、雙精度實數 |
g,G | 以%f或%e中較短的輸出寬度輸出單、雙精度實數 |
c | 輸出單個字符 |
s | 輸出字符串 |
p | 輸出指針地址 |
lu | 32位無符號整數 |
llu | 64位無符號整數 |
flags(標識) | 描述 |
---|---|
- | 在給定的字段寬度內左對齊,默認是右對齊(參見 width 子說明符)。 |
+ | 強制在結果之前顯示加號或減號(+ 或 -),即正數前面會顯示 + 號。默認情況下,只有負數前面會顯示一個 - 號。 |
空格 | 如果沒有寫入任何符號,則在該值前面插入一個空格。 |
# | 與 o、x 或 X 說明符一起使用時,非零值前面會分別顯示 0、0x 或 0X。 與 e、E 和 f 一起使用時,會強制輸出包含一個小數點,即使后邊沒有數字時也會顯示小數點。默認情況下,如果后邊沒有數字時候,不會顯示顯示小數點。 與 g 或 G 一起使用時,結果與使用 e 或 E 時相同,但是尾部的零不會被移除。 |
0 | 在指定填充 padding 的數字左邊放置零(0),而不是空格(參見 width 子說明符)。 |
width(寬度) | 描述 |
---|---|
(number) | 要輸出的字符的最小數目。如果輸出的值短于該數,結果會用空格填充。如果輸出的值長于該數,結果不會被截斷。 |
* | 寬度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
.precision(精度) | 描述 |
---|---|
.number | 對于整數說明符(d、i、o、u、x、X):precision 指定了要寫入的數字的最小位數。如果寫入的值短于該數,結果會用前導零來填充。如果寫入的值長于該數,結果不會被截斷。精度為 0 意味著不寫入任何字符。 對于 e、E 和 f 說明符:要在小數點后輸出的小數位數。 對于 g 和 G 說明符:要輸出的最大有效位數。 對于 s: 要輸出的最大字符數。默認情況下,所有字符都會被輸出,直到遇到末尾的空字符。 對于 c 類型:沒有任何影響。 當未指定任何精度時,默認為 1。如果指定時不帶有一個顯式值,則假定為 0。 |
.* | 精度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
length(長度) | 描述 |
---|---|
h | 參數被解釋為短整型或無符號短整型(僅適用于整數說明符:i、d、o、u、x 和 X)。 |
l | 參數被解釋為長整型或無符號長整型,適用于整數說明符(i、d、o、u、x 和 X)及說明符 c(表示一個寬字符)和 s(表示寬字符字符串)。 |
L | 參數被解釋為長雙精度型(僅適用于浮點數說明符:e、E、f、g 和 G)。 |
-
附加參數?-- 根據不同的 format 字符串,函數可能需要一系列的附加參數,每個參數包含了一個要被插入的值,替換了 format 參數中指定的每個 % 標簽。參數的個數應與 % 標簽的個數相同
【返回值】
如果成功,則返回寫入的字符總數,否則返回一個負數
【TestCode】
【總結】
和fprintf用法類似,只不過fprintf是網文件流里寫數據,而printf是往sdtout輸出數據
注意點:
根據不同的 format 字符串,函數可能需要一系列的附加參數,每個參數包含了一個要被插入的值,替換了 format 參數中指定的每個 % 標簽。參數的個數應與 % 標簽的個數相同
【函數24:sprintf】
【格式】
int sprintf(char *str, const char *format, ...)
【功能】
發送格式化輸出到字符串
【入參】
- str?-- 這是指向一個字符數組的指針,該數組存儲了 C 字符串。
- format?-- 這是字符串,包含了要被寫入到字符串 str 的文本。它可以包含嵌入的 format 標簽,format 標簽可被隨后的附加參數中指定的值替換,并按需求進行格式化。format 標簽屬性是?%[flags][width][.precision][length]specifier,具體講解如下:
specifier(說明符) | 輸出 |
---|---|
c | 字符 |
d 或 i | 有符號十進制整數 |
e | 使用 e 字符的科學科學記數法(尾數和指數) |
E | 使用 E 字符的科學科學記數法(尾數和指數) |
f | 十進制浮點數 |
g | 自動選擇 %e 或 %f 中合適的表示法 |
G | 自動選擇 %E 或 %f 中合適的表示法 |
o | 有符號八進制 |
s | 字符的字符串 |
u | 無符號十進制整數 |
x | 無符號十六進制整數 |
X | 無符號十六進制整數(大寫字母) |
p | 指針地址 |
n | 無輸出 |
% | 字符 |
flags(標識) | 描述 |
---|---|
- | 在給定的字段寬度內左對齊,默認是右對齊(參見 width 子說明符)。 |
+ | 強制在結果之前顯示加號或減號(+ 或 -),即正數前面會顯示 + 號。默認情況下,只有負數前面會顯示一個 - 號。 |
(space) | 如果沒有寫入任何符號,則在該值前面插入一個空格。 |
# | 與 o、x 或 X 說明符一起使用時,非零值前面會分別顯示 0、0x 或 0X。 與 e、E 和 f 一起使用時,會強制輸出包含一個小數點,即使后邊沒有數字時也會顯示小數點。默認情況下,如果后邊沒有數字時候,不會顯示顯示小數點。 與 g 或 G 一起使用時,結果與使用 e 或 E 時相同,但是尾部的零不會被移除。 |
0 | 在指定填充 padding 的數字左邊放置零(0),而不是空格(參見 width 子說明符)。 |
width(寬度) | 描述 |
---|---|
(number) | 要輸出的字符的最小數目。如果輸出的值短于該數,結果會用空格填充。如果輸出的值長于該數,結果不會被截斷。 |
* | 寬度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
.precision(精度) | 描述 |
---|---|
.number | 對于整數說明符(d、i、o、u、x、X):precision 指定了要寫入的數字的最小位數。如果寫入的值短于該數,結果會用前導零來填充。如果寫入的值長于該數,結果不會被截斷。精度為 0 意味著不寫入任何字符。 對于 e、E 和 f 說明符:要在小數點后輸出的小數位數。 對于 g 和 G 說明符:要輸出的最大有效位數。 對于 s: 要輸出的最大字符數。默認情況下,所有字符都會被輸出,直到遇到末尾的空字符。 對于 c 類型:沒有任何影響。 當未指定任何精度時,默認為 1。如果指定時不帶有一個顯式值,則假定為 0。 |
.* | 精度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
length(長度) | 描述 |
---|---|
h | 參數被解釋為短整型或無符號短整型(僅適用于整數說明符:i、d、o、u、x 和 X)。 |
l | 參數被解釋為長整型或無符號長整型,適用于整數說明符(i、d、o、u、x 和 X)及說明符 c(表示一個寬字符)和 s(表示寬字符字符串)。 |
L | 參數被解釋為長雙精度型(僅適用于浮點數說明符:e、E、f、g 和 G)。 |
- 附加參數?-- 根據不同的 format 字符串,函數可能需要一系列的附加參數,每個參數包含了一個要被插入的值,替換了 format 參數中指定的每個 % 標簽。參數的個數應與 % 標簽的個數相同
【返回值】
如果成功,則返回寫入的字符總數,不包括字符串追加在字符串末尾的空字符。如果失敗,則返回一個負數
【TestCode】
【總結】
這個與fprintf和printf用法類似,但是這個是往數組里寫入數據的哦,注意點如下:
1.注意附加參數的使用方法
2.注意數組不要越界
【函數25:vfprintf】
【格式】
int vfprintf(FILE *stream, const char *format, va_list arg)
【功能】
使用參數列表發送格式化輸出到流 stream 中
【入參】
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了流。
- format?-- 這是 C 字符串,包含了要被寫入到流 stream 中的文本。它可以包含嵌入的 format 標簽,format 標簽可被隨后的附加參數中指定的值替換,并按需求進行格式化。format 標簽屬性是?%[flags][width][.precision][length]specifier,具體講解如下:
specifier(說明符) | 輸出 |
---|---|
c | 字符 |
d 或 i | 有符號十進制整數 |
e | 使用 e 字符的科學科學記數法(尾數和指數) |
E | 使用 E 字符的科學科學記數法(尾數和指數) |
f | 十進制浮點數 |
g | 自動選擇 %e 或 %f 中合適的表示法 |
G | 自動選擇 %E 或 %f 中合適的表示法 |
o | 有符號八進制 |
s | 字符的字符串 |
u | 無符號十進制整數 |
x | 無符號十六進制整數 |
X | 無符號十六進制整數(大寫字母) |
p | 指針地址 |
n | 無輸出 |
% | 字符 |
flags(標識) | 描述 |
---|---|
- | 在給定的字段寬度內左對齊,默認是右對齊(參見 width 子說明符)。 |
+ | 強制在結果之前顯示加號或減號(+ 或 -),即正數前面會顯示 + 號。默認情況下,只有負數前面會顯示一個 - 號。 |
(space) | 如果沒有寫入任何符號,則在該值前面插入一個空格。 |
# | 與 o、x 或 X 說明符一起使用時,非零值前面會分別顯示 0、0x 或 0X。 與 e、E 和 f 一起使用時,會強制輸出包含一個小數點,即使后邊沒有數字時也會顯示小數點。默認情況下,如果后邊沒有數字時候,不會顯示顯示小數點。 與 g 或 G 一起使用時,結果與使用 e 或 E 時相同,但是尾部的零不會被移除。 |
0 | 在指定填充 padding 的數字左邊放置零(0),而不是空格(參見 width 子說明符)。 |
width(寬度) | 描述 |
---|---|
(number) | 要輸出的字符的最小數目。如果輸出的值短于該數,結果會用空格填充。如果輸出的值長于該數,結果不會被截斷。 |
* | 寬度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
.precision(精度) | 描述 |
---|---|
.number | 對于整數說明符(d、i、o、u、x、X):precision 指定了要寫入的數字的最小位數。如果寫入的值短于該數,結果會用前導零來填充。如果寫入的值長于該數,結果不會被截斷。精度為 0 意味著不寫入任何字符。 對于 e、E 和 f 說明符:要在小數點后輸出的小數位數。 對于 g 和 G 說明符:要輸出的最大有效位數。 對于 s: 要輸出的最大字符數。默認情況下,所有字符都會被輸出,直到遇到末尾的空字符。 對于 c 類型:沒有任何影響。 當未指定任何精度時,默認為 1。如果指定時不帶有一個顯式值,則假定為 0。 |
.* | 精度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
length(長度) | 描述 |
---|---|
h | 參數被解釋為短整型或無符號短整型(僅適用于整數說明符:i、d、o、u、x 和 X)。 |
l | 參數被解釋為長整型或無符號長整型,適用于整數說明符(i、d、o、u、x 和 X)及說明符 c(表示一個寬字符)和 s(表示寬字符字符串)。 |
L | 參數被解釋為長雙精度型(僅適用于浮點數說明符:e、E、f、g 和 G)。 |
- arg?-- 一個表示可變參數列表的對象。這應被 <stdarg> 中定義的 va_start 宏初始化
【返回值】
如果成功,則返回寫入的字符總數,否則返回一個負數
【TestCode】
【總結】
009_C標準庫函數之<stdarg.h>-CSDN博客
對于可變參數可以看上面這個文章,熟悉后再來使用vfprintf函數,會事半功倍
【函數26:vprintf】
【格式】
int vprintf(const char *format, va_list arg)
【功能】
使用參數列表發送格式化輸出到標準輸出 stdout
【入參】
- format?-- 這是字符串,包含了要被寫入到標準輸出 stdout 的文本。它可以包含嵌入的 format 標簽,format 標簽可被隨后的附加參數中指定的值替換,并按需求進行格式化。format 標簽屬性是?%[flags][width][.precision][length]specifier,具體講解如下:
specifier(說明符) | 輸出 |
---|---|
c | 字符 |
d 或 i | 有符號十進制整數 |
e | 使用 e 字符的科學科學記數法(尾數和指數) |
E | 使用 E 字符的科學科學記數法(尾數和指數) |
f | 十進制浮點數 |
g | 自動選擇 %e 或 %f 中合適的表示法 |
G | 自動選擇 %E 或 %f 中合適的表示法 |
o | 有符號八進制 |
s | 字符的字符串 |
u | 無符號十進制整數 |
x | 無符號十六進制整數 |
X | 無符號十六進制整數(大寫字母) |
p | 指針地址 |
n | 無輸出 |
% | 字符 |
flags(標識) | 描述 |
---|---|
- | 在給定的字段寬度內左對齊,默認是右對齊(參見 width 子說明符)。 |
+ | 強制在結果之前顯示加號或減號(+ 或 -),即正數前面會顯示 + 號。默認情況下,只有負數前面會顯示一個 - 號。 |
(space) | 如果沒有寫入任何符號,則在該值前面插入一個空格。 |
# | 與 o、x 或 X 說明符一起使用時,非零值前面會分別顯示 0、0x 或 0X。 與 e、E 和 f 一起使用時,會強制輸出包含一個小數點,即使后邊沒有數字時也會顯示小數點。默認情況下,如果后邊沒有數字時候,不會顯示顯示小數點。 與 g 或 G 一起使用時,結果與使用 e 或 E 時相同,但是尾部的零不會被移除。 |
0 | 在指定填充 padding 的數字左邊放置零(0),而不是空格(參見 width 子說明符)。 |
width(寬度) | 描述 |
---|---|
(number) | 要輸出的字符的最小數目。如果輸出的值短于該數,結果會用空格填充。如果輸出的值長于該數,結果不會被截斷。 |
* | 寬度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
.precision(精度) | 描述 |
---|---|
.number | 對于整數說明符(d、i、o、u、x、X):precision 指定了要寫入的數字的最小位數。如果寫入的值短于該數,結果會用前導零來填充。如果寫入的值長于該數,結果不會被截斷。精度為 0 意味著不寫入任何字符。 對于 e、E 和 f 說明符:要在小數點后輸出的小數位數。 對于 g 和 G 說明符:要輸出的最大有效位數。 對于 s: 要輸出的最大字符數。默認情況下,所有字符都會被輸出,直到遇到末尾的空字符。 對于 c 類型:沒有任何影響。 當未指定任何精度時,默認為 1。如果指定時不帶有一個顯式值,則假定為 0。 |
.* | 精度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
length(長度) | 描述 |
---|---|
h | 參數被解釋為短整型或無符號短整型(僅適用于整數說明符:i、d、o、u、x 和 X)。 |
l | 參數被解釋為長整型或無符號長整型,適用于整數說明符(i、d、o、u、x 和 X)及說明符 c(表示一個寬字符)和 s(表示寬字符字符串)。 |
L | 參數被解釋為長雙精度型(僅適用于浮點數說明符:e、E、f、g 和 G)。 |
- arg?-- 一個表示可變參數列表的對象。這應被 <stdarg> 中定義的 va_start 宏初始化
【返回值】
如果成功,則返回寫入的字符總數,否則返回一個負數
【TestCode】
【總結】
記得在使用vprintf的時候,一定要包含stdarg.h頭文件,因為有va_list args;變量需要定義
說實話,我感覺這個vprintf和printf函數沒多大區別,都是往終端輸出自定義內容格式的,為啥要這么搞?有清楚的大神麻煩解釋下,小弟在此謝過,3Q
【函數27:vsprintf】
【格式】
int vsprintf(char *str, const char *format, va_list arg)
【功能】
使用參數列表發送格式化輸出到字符串
【入參】
- str?-- 這是指向一個字符數組的指針,該數組存儲了 C 字符串。
- format?-- 這是字符串,包含了要被寫入到字符串 str 的文本。它可以包含嵌入的 format 標簽,format 標簽可被隨后的附加參數中指定的值替換,并按需求進行格式化。format 標簽屬性是?%[flags][width][.precision][length]specifier,具體講解如下:
specifier(說明符) | 輸出 |
---|---|
c | 字符 |
d 或 i | 有符號十進制整數 |
e | 使用 e 字符的科學科學記數法(尾數和指數) |
E | 使用 E 字符的科學科學記數法(尾數和指數) |
f | 十進制浮點數 |
g | 自動選擇 %e 或 %f 中合適的表示法 |
G | 自動選擇 %E 或 %f 中合適的表示法 |
o | 有符號八進制 |
s | 字符的字符串 |
u | 無符號十進制整數 |
x | 無符號十六進制整數 |
X | 無符號十六進制整數(大寫字母) |
p | 指針地址 |
n | 無輸出 |
% | 字符 |
flags(標識) | 描述 |
---|---|
- | 在給定的字段寬度內左對齊,默認是右對齊(參見 width 子說明符)。 |
+ | 強制在結果之前顯示加號或減號(+ 或 -),即正數前面會顯示 + 號。默認情況下,只有負數前面會顯示一個 - 號。 |
(space) | 如果沒有寫入任何符號,則在該值前面插入一個空格。 |
# | 與 o、x 或 X 說明符一起使用時,非零值前面會分別顯示 0、0x 或 0X。 與 e、E 和 f 一起使用時,會強制輸出包含一個小數點,即使后邊沒有數字時也會顯示小數點。默認情況下,如果后邊沒有數字時候,不會顯示顯示小數點。 與 g 或 G 一起使用時,結果與使用 e 或 E 時相同,但是尾部的零不會被移除。 |
0 | 在指定填充 padding 的數字左邊放置零(0),而不是空格(參見 width 子說明符)。 |
width(寬度) | 描述 |
---|---|
(number) | 要輸出的字符的最小數目。如果輸出的值短于該數,結果會用空格填充。如果輸出的值長于該數,結果不會被截斷。 |
* | 寬度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
.precision(精度) | 描述 |
---|---|
.number | 對于整數說明符(d、i、o、u、x、X):precision 指定了要寫入的數字的最小位數。如果寫入的值短于該數,結果會用前導零來填充。如果寫入的值長于該數,結果不會被截斷。精度為 0 意味著不寫入任何字符。 對于 e、E 和 f 說明符:要在小數點后輸出的小數位數。 對于 g 和 G 說明符:要輸出的最大有效位數。 對于 s: 要輸出的最大字符數。默認情況下,所有字符都會被輸出,直到遇到末尾的空字符。 對于 c 類型:沒有任何影響。 當未指定任何精度時,默認為 1。如果指定時不帶有一個顯式值,則假定為 0。 |
.* | 精度在 format 字符串中未指定,但是會作為附加整數值參數放置于要被格式化的參數之前。 |
length(長度) | 描述 |
---|---|
h | 參數被解釋為短整型或無符號短整型(僅適用于整數說明符:i、d、o、u、x 和 X)。 |
l | 參數被解釋為長整型或無符號長整型,適用于整數說明符(i、d、o、u、x 和 X)及說明符 c(表示一個寬字符)和 s(表示寬字符字符串)。 |
L | 參數被解釋為長雙精度型(僅適用于浮點數說明符:e、E、f、g 和 G)。 |
- arg?-- 一個表示可變參數列表的對象。這應被 <stdarg> 中定義的 va_start 宏初始化
【返回值】
如果成功,則返回寫入的字符總數,否則返回一個負數
【TestCode】
【總結】
1.vsprintf主要是往字符數組里寫入固定格式的字符內容
2.返回值字符總數并不包括結束符'\0'
【函數28:fscnaf】
【格式】
int fscanf(FILE *stream, const char *format, ...)
【功能】
從流 stream 讀取格式化輸入
【入參】
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了流。
- format?-- 這是 C 字符串,包含了以下各項中的一個或多個:空格字符、非空格字符?和?format 說明符。
format 說明符形式為?[=%[*][width][modifiers]type=],具體講解如下:
參數 | 描述 |
---|---|
* | 這是一個可選的星號,表示數據是從流 stream 中讀取的,但是可以被忽視,即它不存儲在對應的參數中。 |
width | 這指定了在當前讀取操作中讀取的最大字符數。 |
modifiers | 為對應的附加參數所指向的數據指定一個不同于整型(針對 d、i 和 n)、無符號整型(針對 o、u 和 x)或浮點型(針對 e、f 和 g)的大小: h :短整型(針對 d、i 和 n),或無符號短整型(針對 o、u 和 x) l :長整型(針對 d、i 和 n),或無符號長整型(針對 o、u 和 x),或雙精度型(針對 e、f 和 g) L :長雙精度型(針對 e、f 和 g) |
type | 一個字符,指定了要被讀取的數據類型以及數據讀取方式。具體參見下一個表格。 |
fscanf 類型說明符:
類型 | 合格的輸入 | 參數的類型 |
---|---|---|
c | 單個字符:讀取下一個字符。如果指定了一個不為 1 的寬度 width,函數會讀取 width 個字符,并通過參數傳遞,把它們存儲在數組中連續位置。在末尾不會追加空字符。 | char * |
d | 十進制整數:數字前面的 + 或 - 號是可選的。 | int * |
e,E,f,g,G | 浮點數:包含了一個小數點、一個可選的前置符號 + 或 -、一個可選的后置字符 e 或 E,以及一個十進制數字。兩個有效的實例 -732.103 和 7.12e4 | float * |
o | 八進制整數。 | int * |
s | 字符串。這將讀取連續字符,直到遇到一個空格字符(空格字符可以是空白、換行和制表符)。 | char * |
u | 無符號的十進制整數。 | unsigned int * |
x,X | 十六進制整數。 | int * |
- 附加參數?-- 根據不同的 format 字符串,函數可能需要一系列的附加參數,每個參數包含了一個要被插入的值,替換了 format 參數中指定的每個 % 標簽。參數的個數應與 % 標簽的個數相同
【返回值】
如果成功,該函數返回成功匹配和賦值的個數。如果到達文件末尾或發生讀錯誤,則返回 EOF
【TestCode】
【總結】
注意下面這段代碼:
我們看下w和w+的區別,如下:
就是說w會創建一個用于寫入的空文件,這個模式下是不支持讀的,所以我們會返回EOF(-1);w+模式是支持讀寫的,所以我們讀的時候是OK的哦,那么如果我們就是想用w,怎么辦呢?如下:
還有就是注意:fscnaf是以format格式從文件流中讀出數據再寫入變量中,供我們使用的!
【函數29:scanf】
【格式】
int scanf(const char *format, ...)
【功能】
從標準輸入 stdin 讀取格式化輸入
【入參】
- format?-- 這是 C 字符串,包含了以下各項中的一個或多個:空格字符、非空格字符?和?format 說明符。
format 說明符形式為:
[=%[*][width][modifiers]type=]
具體講解如下:
參數 | 描述 |
---|---|
* | 這是一個可選的星號,表示數據是從流 stream 中讀取的,但是可以被忽視,即它不存儲在對應的參數中。 |
width | 這指定了在當前讀取操作中讀取的最大字符數。 |
modifiers | 為對應的附加參數所指向的數據指定一個不同于整型(針對 d、i 和 n)、無符號整型(針對 o、u 和 x)或浮點型(針對 e、f 和 g)的大小: h :短整型(針對 d、i 和 n),或無符號短整型(針對 o、u 和 x) l :長整型(針對 d、i 和 n),或無符號長整型(針對 o、u 和 x),或雙精度型(針對 e、f 和 g) L :長雙精度型(針對 e、f 和 g) |
type | 一個字符,指定了要被讀取的數據類型以及數據讀取方式。具體參見下一個表格。 |
scanf 類型說明符:
類型 | 合格的輸入 | 參數的類型 |
---|---|---|
%a、%A | 讀入一個浮點值(僅 C99 有效)。 | float * |
%c | 單個字符:讀取下一個字符。如果指定了一個不為 1 的寬度 width,函數會讀取 width 個字符,并通過參數傳遞,把它們存儲在數組中連續位置。在末尾不會追加空字符。 | char * |
%d | 十進制整數:數字前面的 + 或 - 號是可選的。 | int * |
%e、%E、%f、%F、%g、%G | 浮點數:包含了一個小數點、一個可選的前置符號 + 或 -、一個可選的后置字符 e 或 E,以及一個十進制數字。兩個有效的實例 -732.103 和 7.12e4 | float * |
%i | 讀入十進制,八進制,十六進制整數 。 | int * |
%o | 八進制整數。 | int * |
%s | 字符串。這將讀取連續字符,直到遇到一個空格字符(空格字符可以是空白、換行和制表符)。 | char * |
%u | 無符號的十進制整數。 | unsigned int * |
%x、%X | 十六進制整數。 | int * |
%p | 讀入一個指針 。 | |
%[] | 掃描字符集合 。 | |
%% | 讀 % 符號。 |
- 附加參數?-- 根據不同的 format 字符串,函數可能需要一系列的附加參數,每個參數包含了一個要被插入的值,替換了 format 參數中指定的每個 % 標簽。參數的個數應與 % 標簽的個數相同
【返回值】
如果成功,該函數返回成功匹配和賦值的個數。如果到達文件末尾或發生讀錯誤,則返回 EOF
【TestCode】
沒有逗號的輸入
有逗號的輸入
【總結】
這樣的時候會亂碼,為什么?因為str比較大,會把所有的輸入都裝進去,目前最好的解決方法就是放到末尾進行輸入,如下:
scanf的輸入會根據格式而有所不同,所以這個一定要謹慎,一定要驗證驗證驗證!
【函數30:sscanf】
【格式】
int sscanf(const char *str, const char *format, ...)
【功能】
從字符串讀取格式化輸入
【入參】
- str?-- 這是 C 字符串,是函數檢索數據的源。
- format?-- 這是 C 字符串,包含了以下各項中的一個或多個:空格字符、非空格字符?和?format 說明符。
format 說明符形式為?[=%[*][width][modifiers]type=],具體講解如下:
參數 | 描述 |
---|---|
* | 這是一個可選的星號,表示數據是從流 stream 中讀取的,但是可以被忽視,即它不存儲在對應的參數中。 |
width | 這指定了在當前讀取操作中讀取的最大字符數。 |
modifiers | 為對應的附加參數所指向的數據指定一個不同于整型(針對 d、i 和 n)、無符號整型(針對 o、u 和 x)或浮點型(針對 e、f 和 g)的大小: h :短整型(針對 d、i 和 n),或無符號短整型(針對 o、u 和 x) l :長整型(針對 d、i 和 n),或無符號長整型(針對 o、u 和 x),或雙精度型(針對 e、f 和 g) L :長雙精度型(針對 e、f 和 g) |
type | 一個字符,指定了要被讀取的數據類型以及數據讀取方式。具體參見下一個表格。 |
sscanf 類型說明符:
類型 | 合格的輸入 | 參數的類型 |
---|---|---|
c | 單個字符:讀取下一個字符。如果指定了一個不為 1 的寬度 width,函數會讀取 width 個字符,并通過參數傳遞,把它們存儲在數組中連續位置。在末尾不會追加空字符。 | char * |
d | 十進制整數:數字前面的 + 或 - 號是可選的。 | int * |
e,E,f,g,G | 浮點數:包含了一個小數點、一個可選的前置符號 + 或 -、一個可選的后置字符 e 或 E,以及一個十進制數字。兩個有效的實例 -732.103 和 7.12e4 | float * |
o | 八進制整數。 | int * |
s | 字符串。這將讀取連續字符,直到遇到一個空格字符(空格字符可以是空白、換行和制表符)。 | char * |
u | 無符號的十進制整數。 | unsigned int * |
x,X | 十六進制整數。 | int * |
- 附加參數?-- 這個函數接受一系列的指針作為附加參數,每一個指針都指向一個對象,對象類型由 format 字符串中相應的 % 標簽指定,參數與 % 標簽的順序相同。
針對檢索數據的 format 字符串中的每個 format 說明符,應指定一個附加參數。如果您想要把 sscanf 操作的結果存儲在一個普通的變量中,您應該在標識符前放置引用運算符(&)
【返回值】
如果成功,該函數返回成功匹配和賦值的個數。如果到達文件末尾或發生讀錯誤,則返回 EOF
【TestCode】
【總結】
注意區分fscanf和sscanf的區別:fscanf是從文件流中讀取數據內容,填寫到變量中;sscanf是從串中讀取數據內容,填寫到變量中,兩者的源文件目標不同,但是格式和目的變量是一樣的用法哦
【函數31:fgetc】
【格式】
int fgetc(FILE *stream)
【功能】
從指定的流 stream 獲取下一個字符(一個無符號字符),并把位置標識符往前移動
【入參】
stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了要在上面執行操作的流
【返回值】
該函數以無符號 char 強制轉換為 int 的形式返回讀取的字符,如果到達文件末尾或發生讀錯誤,則返回 EOF
【TestCode】
【總結】
fgetc函數是逐一的去讀取字符,完后,光標向后自動移動一格,所以我們讀取的時候要使用do_while結構去操作下,條件就是feof函數去檢測是否到了文件流末尾
【函數32:fgets】
【格式】
char *fgets(char *str, int n, FILE *stream)
【功能】
從指定的流 stream 讀取一行,并把它存儲在 str 所指向的字符串內。當讀取 (n-1) 個字符時,
或者讀取到換行符時,或者到達文件末尾時,它會停止,具體視情況而定
【入參】
- str?-- 這是指向一個字符數組的指針,該數組存儲了要讀取的字符串。
- n?-- 這是要讀取的最大字符數(包括最后的空字符)。通常是使用以 str 傳遞的數組長度。
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了要從中讀取字符的流
【返回值】
如果成功,該函數返回相同的 str 參數。如果到達文件末尾或者沒有讀取到任何字符,str 的內容保持不變,并返回一個空指針。如果發生錯誤,返回一個空指針
【TestCode】
讀取一行的情況:
讀取多行時,如下:
明顯不是我們想要的結果,那么該如何做呢?如下:
【總結】
fgets雖然是讀取整行,但是一定要注意它遇到換行符時,或者到達文件末尾時,它會停止,具體視情況而定,這個一定要記住,不然可能讀取的內容并非你想要的內容
【函數33:fputc】
【格式】
int fputc(int char, FILE *stream)
【功能】
把參數 char 指定的字符(一個無符號字符)寫入到指定的流 stream 中,并把位置標識符往前移動
【入參】
- char?-- 這是要被寫入的字符。該字符以其對應的 int 值進行傳遞。
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了要被寫入字符的流
【返回值】
如果沒有發生錯誤,則返回被寫入的字符。如果發生錯誤,則返回 EOF,并設置錯誤標識符
【TestCode】
【總結】
fputc是逐一將字符寫入文件流中,所以一般都需要用到for循環或者do_while結構
【函數34:fputs】
【格式】
int fputs(const char *str, FILE *stream)
【功能】
把字符串寫入到指定的流 stream 中,但不包括空字符
【入參】
- str?-- 這是一個數組,包含了要寫入的以空字符終止的字符序列。
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了要被寫入字符串的流
【返回值】
該函數返回一個非負值,如果發生錯誤則返回 EOF
【TestCode】
【總結】
注意,多行寫入的時候,使用fputs的話,它不會自動換行的哦
想要換行的話,就自己加,如下:
【函數35:getc】
【格式】
int getc(FILE *stream)
【功能】
從指定的流 stream 獲取下一個字符(一個無符號字符),并把位置標識符往前移動
【入參】
stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了要在上面執行操作的流
【返回值】
該函數以無符號 char 強制轉換為 int 的形式返回讀取的字符,如果到達文件末尾或發生讀錯誤,則返回 EOF
【TestCode】
從文件流讀取內容:
從stdin獲取內容:
【總結】
1.關于stdin和stdout在linux的時候會經常用到,那么我們先簡單說下,一個文件一般都有:標準輸入,標準輸出,標準錯誤輸入,分別定義為0,1,2,對應的就是stdin,stdout,stderr,
2.getc感覺和scanf有些相似,但是還是區別很大的:scanf是獲取輸入的內容,這個內容不僅僅是字符哦,而且scanf只能從標準輸入stdin獲取;而getc只是獲取一個字符,不僅可以從文件流利獲取的,而且也可以從標準輸入stdin獲取哦
【函數36:getchar】
【格式】
int getchar(void)
【功能】
從標準輸入 stdin 獲取一個字符(一個無符號字符)
【入參】
void:空入參
【返回值】
該函數以無符號 char 強制轉換為 int 的形式返回讀取的字符,如果到達文件末尾或發生讀錯誤,則返回 EOF
【TestCode】
【總結】
getc和getchar還是有些區別的,前者是從文件流或者標準輸入(stdin)中獲取字符,是必須要有入參的,而后者是從標準輸入(stdin)中獲取字符的,但是不需要入參哦
【函數37:gets】
【格式】
char *gets(char *str)
【功能】
從標準輸入 stdin 讀取一行,并把它存儲在 str 所指向的字符串中。
當讀取到換行符時,或者到達文件末尾時,它會停止,具體視情況而定
【入參】
str?-- 這是指向一個字符數組的指針,該數組存儲了 C 字符串
【返回值】
如果成功,該函數返回 str。如果發生錯誤或者到達文件末尾時還未讀取任何字符,則返回 NULL
【TestCode】
【總結】
1.gets的返回值是str的地址
2.gets的入參是要填入字符串的那個數組的地址
【函數38:putc】
【格式】
int putc(int char, FILE *stream)
【功能】
把參數 char 指定的字符(一個無符號字符)寫入到指定的流 stream 中,并把位置標識符往前移動
【入參】
- char?-- 這是要被寫入的字符。該字符以其對應的 int 值進行傳遞。
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了要被寫入字符的流
【返回值】
該函數以無符號 char 強制轉換為 int 的形式返回寫入的字符,如果發生錯誤則返回 EOF
【TestCode】
【總結】
putc和fputc幾乎是一樣的作用,那么到底有啥區別呢?
1.返回值區別
2.fputc一旦發生錯誤,會給文件設置錯誤標識符,但是putc并不會這樣
【函數39:putchar】
【格式】
int putchar(int char)
【功能】
把參數 char 指定的字符(一個無符號字符)寫入到標準輸出 stdout 中
【入參】
char?-- 這是要被寫入的字符。該字符以其對應的 int 值進行傳遞
【返回值】
該函數以無符號 char 強制轉換為 int 的形式返回寫入的字符,如果發生錯誤則返回 EOF。
【TestCode】
【總結】
putchar函數是將輸出直接輸出到標準輸出上的哦
【函數40:puts】
【格式】
int puts(const char *str)
【功能】
把一個字符串寫入到標準輸出 stdout,直到空字符,但不包括空字符。
換行符會被追加到輸出中
【入參】
str?-- 這是要被寫入的 C 字符串
【返回值】
如果成功,該函數返回一個非負值為字符串長度(包括末尾的?\0),如果發生錯誤則返回 EOF
【TestCode】
【總結】
這個是直接輸出到終端上,和putchar也是有些區別的,請仔細思考一下下
【函數41:ungetc】
【格式】
int ungetc(int char, FILE *stream)
【功能】
把字符 char(一個無符號字符)推入到指定的流 stream 中,以便它是下一個被讀取到的字符
【入參】
- char?-- 這是要被推入的字符。該字符以其對應的 int 值進行傳遞。
- stream?-- 這是指向 FILE 對象的指針,該 FILE 對象標識了輸入流
【返回值】
如果成功,則返回被推入的字符,否則返回 EOF,且流 stream 保持不變
【TestCode】
【總結】
注意理解這句話:把字符 char(一個無符號字符)推入到指定的流 stream 中,以便它是下一個被讀取到的字符;尤其后半句:這句意思并不是替換那個字符,而是在那個字符后面推入你要加入的字符,并不是替換原來的字符哦
【函數42:perror】
【格式】
void perror(const char *str)
【功能】
把一個描述性錯誤消息輸出到標準錯誤 stderr。
首先輸出字符串 str,后跟一個冒號,然后是一個空格
【入參】
str?-- 這是 C 字符串,包含了一個自定義消息,將顯示在原本的錯誤消息之前
【返回值】
該函數不返回任何值
【TestCode】
【總結】
perror的入參const char* str就是你要編輯的額debug信息或者標注性打印信息,以便于出問題的時候,能快速的定位到對應的問題點
【函數43:snprintf】
【格式】
int snprintf(char *str, size_t size, const char *format, ...)
【功能】
把格式字符串寫到 str 中
【入參】
- str?-- 目標字符串,用于存儲格式化后的字符串的字符數組的指針。
- size?-- 字符數組的大小。
- format?-- 格式化字符串。
- ...?-- 可變參數,可變數量的參數根據 format 中的格式化指令進行格式化
【返回值】
snprintf() 函數的返回值是輸出到 str 緩沖區中的字符數,不包括字符串結尾的空字符 \0。如果 snprintf() 輸出的字符數超過了 size 參數指定的緩沖區大小,則輸出的結果會被截斷,只有 size - 1 個字符被寫入緩沖區,最后一個字符為字符串結尾的空字符 \0。
需要注意的是,snprintf() 函數返回的字符數并不包括字符串結尾的空字符 \0,因此如果需要將輸出結果作為一個字符串使用,則需要在緩沖區的末尾添加一個空字符 \0
【TestCode】
【總結】
snprintf() 是一個 C 語言標準庫函數,用于格式化輸出字符串,并將結果寫入到指定的緩沖區,與 sprintf() 不同的是,snprintf() 會限制輸出的字符數,避免緩沖區溢出。
C 庫函數?int snprintf(char *str, size_t size, const char *format, ...)?設將可變參數(...)按照?format?格式化成字符串,并將字符串復制到?str?中,size?為要寫入的字符的最大數目,超過?size?會被截斷,最多寫入 size-1 個字符。
與?sprintf()?函數不同的是,snprintf() 函數提供了一個參數 size,可以防止緩沖區溢出。如果格式化后的字符串長度超過了 size-1,則 snprintf() 只會寫入 size-1 個字符,并在字符串的末尾添加一個空字符(\0)以表示字符串的結束
注意事項:
-
緩沖區大小:
snprintf()
?函數會限制輸出的字符數,但是需要確保傳入的緩沖區大小足夠,以便容納格式化后的字符串。否則,字符串可能會截斷,導致信息丟失。 -
字符串結束符:
snprintf()
?函數會在緩沖區最后添加一個空字符作為字符串的結束符,但這個字符不計入返回值中。因此,在使用?snprintf()
?輸出字符串時,需要確保緩沖區的大小足夠,以便容納字符串的所有字符以及結尾的空字符。 -
格式化字符串:在使用?
snprintf()
?格式化字符串時,需要確保格式化字符串中的格式說明符和可變參數的類型相匹配。否則,輸出的結果可能會出現錯誤。 -
返回值:
snprintf()
?函數的返回值為寫入緩沖區的字符數,但不包括字符串結尾的空字符。如果返回值等于緩沖區的大小,則表明輸出的結果被截斷了。 -
可變參數:
snprintf()
?函數的可變參數是通過?...
?傳遞的,這意味著需要使用與格式說明符相匹配的類型傳遞可變參數。在使用可變參數時,應該避免使用未初始化的變量,否則會出現不可預測的結果。
總之,在使用 snprintf() 函數時,需要注意緩沖區大小、字符串結束符、格式化字符串、返回值和可變參數等問題,以確保輸出結果正確無誤。