014_C標準庫函數之<stdio.h>

【背景】

今天這個主要說的是<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 中定義的變量類型:

序號變量 & 描述
1size_t
這是無符號整數類型,它是?sizeof?關鍵字的結果。
2FILE
這是一個適合存儲文件流信息的對象類型。
3fpos_t
這是一個適合存儲文件中任何位置的對象類型。

庫宏

下面是頭文件 stdio.h 中定義的宏:

序號宏 & 描述
1NULL
這個宏是一個空指針常量的值。
2_IOFBF、_IOLBF?和?_IONBF
這些宏擴展了帶有特定值的整型常量表達式,并適用于?setvbuf?函數的第三個參數。
3BUFSIZ
這個宏是一個整數,該整數代表了?setbuf?函數使用的緩沖區大小。
4EOF
這個宏是一個表示已經到達文件結束的負整數。
5FOPEN_MAX
這個宏是一個整數,該整數代表了系統可以同時打開的文件數量。
6FILENAME_MAX
這個宏是一個整數,該整數代表了字符數組可以存儲的文件名的最大長度。如果實現沒有任何限制,則該值應為推薦的最大值。
7L_tmpnam
這個宏是一個整數,該整數代表了字符數組可以存儲的由 tmpnam 函數創建的臨時文件名的最大長度。
8SEEK_CUR、SEEK_END?和?SEEK_SET
這些宏是在?fseek?函數中使用,用于在一個文件中定位不同的位置。
9TMP_MAX
這個宏是 tmpnam 函數可生成的獨特文件名的最大數量。
10stderr、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輸出指針地址
lu32位無符號整數
llu64位無符號整數

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.12e4float *
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.12e4float *
%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.12e4float *
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() 函數時,需要注意緩沖區大小、字符串結束符、格式化字符串、返回值和可變參數等問題,以確保輸出結果正確無誤。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15045.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15045.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15045.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LeetCode/NowCoder-鏈表經典算法OJ練習3

孜孜不倦&#xff1a;孜孜&#xff1a;勤勉&#xff0c;不懈怠。指工作或學習勤奮不知疲倦。&#x1f493;&#x1f493;&#x1f493; 目錄 說在前面 題目一&#xff1a;返回倒數第k個節點 題目二&#xff1a;鏈表的回文結構 題目三&#xff1a;相交鏈表 SUMUP結尾 說在前…

Pytorch: 解決因pytorch版本不同 導致訓練ckpt加載失敗

大家都會遇到在工程項目實施階段&#xff0c;如果訓練的模型文件在不同的torch版本環境下部署時&#xff0c;會報錯~。 報錯舉例 # 查看torch環境 import torch print(torch.__version__)# 訓練時環境&#xff1a;torch 1.8.2cu111 # 部署時環境&#xff1a;torch 1.4.0torch.…

dcatAdmin框架 使用phpword 生成word文件

下載phpword插件 composer require phpoffice/phpword 生成word文件接口 static public function word(){//接收傳值$order_id request()->get(order_id);$tpl_id request()->get(tpl_id);//查詢出對應的數據以及關聯數據$sale_order \App\Models\SaleOrder::with([…

Python異步編程之基礎概念

Python異步編程之基礎概念 在現代編程中&#xff0c;異步編程是一種重要的技術&#xff0c;尤其是在處理I/O密集型任務時&#xff0c;異步編程可以大大提高程序的性能和響應速度。本文將介紹Python異步編程的基礎概念&#xff0c;幫助你理解其原理和應用。 什么是異步編程&am…

【代碼隨想錄算法訓練營第37期 第十七天 | LeetCode110.平衡二叉樹、257. 二叉樹的所有路徑、404.左葉子之和】

代碼隨想錄算法訓練營第37期 第十七天 | LeetCode110.平衡二叉樹、257. 二叉樹的所有路徑、404.左葉子之和 一、110.平衡二叉樹 解題代碼C&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *righ…

三、NVIDIA Jetson Orin開發板-GPU加速

一、NVIDIA Jetson Orin開發板的硬件情況 df -h#查看操作系統情況Filesystem Size Used Avail Use% Mounted on **/dev/nvme0n1p1** 234G 17G 208G 8% / none 7.4G 0 7.4G 0% /dev tmpfs 7.6G 0 7.6G 0% /dev/shm tmpfs …

LeetCode 2644.找出可整除性得分最大的整數:暴力模擬(兩層循環)

【LetMeFly】2644.找出可整除性得分最大的整數&#xff1a;暴力模擬&#xff08;兩層循環&#xff09; 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/find-the-maximum-divisibility-score/ 給你兩個下標從 0 開始的整數數組 nums 和 divisors 。 divisors[i] 的 …

MySQL庫/表/數據的操作

文章目錄 1.數據庫操作1.1 創建、刪除、查看和修改1.2 編碼格式1.3 備份和恢復 2.表的操作2.1 創建表2.2 存儲引擎2.3 查看表、修改表、刪除表 3.數據類型3.1整數類型3.2字節類型(bit)3.3浮點類型(bit)3.4 decimal3.5 字符串類型3.6 日期和時間類型3.7 enum和set關于如何查找想…

webpack 學習之 五大核心

為什么用 webpack webpack 官網傳送門 … 官網&#xff1a;webpack 是一個用于現代 JavaScript 應用程序的 靜態模塊打包工具。將你項目中所需的每一個模塊組合成一個或多個 bundles&#xff0c;它們均為靜態資源&#xff0c;用于展示你的內容。總結&#xff1a;匯總所有模塊…

Python中別再用 ‘+‘ 拼接字符串了!

大家好&#xff0c;在 Python 編程中&#xff0c;我們常常需要對字符串進行拼接。你可能會自然地想到用 操作符將字符串連接起來&#xff0c;畢竟這看起來簡單明了。 在 Python 中&#xff0c;字符串是不可變的數據類型&#xff0c;這意味著一旦字符串被創建&#xff0c;它就…

【Python】—— lambda表達式

目錄 &#xff08;一&#xff09;應用場景 &#xff08;二&#xff09;lambda 語法 &#xff08;三&#xff09;示例分析 &#xff08;四&#xff09;lambda參數形式 4.1 無參數 4.2 一個參數 4.3 默認參數 4.4 可變參數 &#xff1a;*args 4.5 可變參數 &#xff1a;…

【Python爬蟲】案例_github模擬登錄

import requests import re from datetime import datetimedef login():sessionrequests.session()session.headers {User-Agent :XXXX #寫自己的}url1 https://github.com/loginres_1 session.get(url1).content.decode()token re.findall(name"authenticity_token&q…

基于Matlab實現BP神經網絡的手寫數字識別

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 一、項目背景與意義 手寫數字識別是計算機視覺和模式識別領域的一個經典問題&#xff0c;具有廣泛的應用場景&…

信息安全從業者書單推薦

作為一名網安人&#xff0c;身上肩負的責任是很大的&#xff0c;能力越大&#xff0c;責任也越大&#xff0c;反過來責任越大&#xff0c;能力也必須跟得上。不管是想進這行&#xff0c;還是已經在這行&#xff0c;持續學習肯定是不能缺少的&#xff0c;除了在工作中積累&#…

qt多語言翻譯不生效的原因

假設您有QT語言家的基礎知識&#xff0c;假設網上那些所有的問題您都已經排查過了&#xff0c;但依然翻譯不生效&#xff0c;那么可以看下這篇帖子&#xff0c;其實就一個問題&#xff0c;變量的生命周期&#xff0c;假設QTranslator是一個函數內的變量&#xff0c;且沒有被聲明…

億圖圖示——刪除水印

一、文件以PPT格式導出 二、點擊水印所在區域&#xff0c;點擊多次delete鍵 三、調整PPT頁面尺寸 四、轉成PDF 五、PDF轉成圖片

Spring的Profile功能及其應用場景

Spring的Profile功能是一種條件化配置機制&#xff0c;它允許開發者根據不同的運行環境或條件來定義和使用不同的bean和配置。Profile功能使得Spring應用程序可以靈活地適應不同的部署場景&#xff0c;而無需修改代碼。 Profile功能的作用&#xff1a; 環境隔離&#xff1a;可…

從0開始寫一個環境保護網站的第3天(JAVAWEB)

1.目標 實現首頁的環境保護原因的查詢&#xff0c;和底部友情連接部分 2.實現 2.1建立數據庫表格&#xff08;這里數據全是百度查詢&#xff09; 環境保護原因表&#xff1a; 友情連接表&#xff1a;&#xff08;數據來源https://zhuanlan.zhihu.com/p/696243646&#xff0…

SqlSession是什么?在MyBatis-Spring中有什么應用?

目錄 一、SqlSession是什么 二、SqlSession在MyBatis中的應用 三、SqlSession在Spring中的應用 一、SqlSession是什么 SqlSession 是 MyBatis 框架中的一個核心概念&#xff0c;它代表與數據庫的一次會話。MyBatis 是一個流行的 Java 持久層框架&#xff0c;用于簡化數據庫…

c++題目_農場和奶牛

&#x1d435;B 頭奶牛 (1≤&#x1d435;≤25000)(1≤B≤25000)&#xff0c;有 &#x1d441;(2&#x1d435;≤&#x1d441;≤50000)N(2B≤N≤50000) 個農場&#xff0c;編號 11 到 &#x1d441;N&#xff0c;有 &#x1d440;(&#x1d441;?1≤&#x1d440;≤100000)M(…