1 原型int fscanf(FILE *stream, const char* format, …) 功能: 從stream流中連續(xù)讀取能夠匹配format格式的字符到參數(shù)列表中對應的變量里。 參數(shù): “stream”是FILE指針類型變量,它指向一個真實的流對象。 “format”是C字符串,由“空格”、“非空格”及“轉換符”組成。具體格式為%[*][width][modifiers]type。見2.1與format參數(shù)相關的概念。 “…”是與“format”中“轉換符”對應變量地址的列表,兩地址間用逗號隔開。 返回值:成功時返回從流中讀取成功的數(shù)據(jù)的個數(shù)。失敗時返回-1(Debian Linux)。 頭文件:2 使用fscanf()2.1與format參數(shù)相關的概念fscanf()的format參數(shù)允許的格式為:“%[*][width][modifiers]type”。[]中的內(nèi)容根據(jù)需要供選,可缺省,%type必須要有,不可省。 %:是format參數(shù)的起始符號,不可缺少。 %[modifiers]type:表一種類型轉換符,如%hd表示short int類型轉換符。它是format的核心。轉換符的作用是將“數(shù)據(jù)”轉換為轉換符代表的數(shù)據(jù)類型,這里提到的數(shù)據(jù)必須能夠轉換為轉換符代表的數(shù)據(jù)類型,fscanf讀取數(shù)據(jù)時也只匹配這樣的數(shù)據(jù)。如pF指向一文件,其中只包含數(shù)據(jù)[123 [空格] 456],用“fscanf(pF, “%d”, &m);”語句是將123這個數(shù)據(jù)轉換為轉換符”%d”所代表的數(shù)據(jù)類型即整型后保存到&m地址中去。 %*[modifiers]type: 表示跳過stream流中能夠被轉換為[modifiers]type所代表數(shù)據(jù)類型的數(shù)據(jù)不讀,如在以上的文件中,用“fscanf(pF, “%*d%d”, &m);”就可以跳過對123的讀取,而將456轉換為整型后保存到&m地址中。%*m[modifiers]type表跳過stream流中能夠被轉換為[modifiers]type所代表數(shù)據(jù)類型的m個“字符”不讀。如“fscanf(pF,“%*1d%d”, &m);”是將23轉換為整型后保存到&m地址中去。 2.2 fscanf()例子fscanf()可以用于讀取文件流中的數(shù)據(jù)。現(xiàn)設有一個文件內(nèi)容如下,Figure1:ffReadFile.dat文件 擁有3個數(shù)字行的最后一個數(shù)字決定擁有兩個數(shù)字的行數(shù)。用fscanf()函數(shù)讀取其內(nèi)的內(nèi)容以筆記到fscanf()函數(shù)的用法。 2.2.1 fscanf()對空格的處理用fopen成功打開ffReadFile.dat文件后,單用以下語句讀取文件的第一行內(nèi)容:re = fscanf(pF, '%d%d%d', &oLine.p, &oLine.l, &oLine.x);if( 3 == re){ //Print on stdout printf('%d\t%d\t%d\n', oLine.p, oLine.l, oLine.x);} 此時,可以正確的打印第一行內(nèi)容到屏幕之上。fscanf()函數(shù)讀取第一行三個數(shù)據(jù)的過程如下: Figure2:fscanf()函數(shù)讀取數(shù)據(jù)過程 文件指針最開始指向ffReadFile.dat的第一個字符(即1)處,然后fscanf()根據(jù)“format”中的第一個“轉換符”讀取文件中的內(nèi)容直到不符合當前“轉換符”能夠轉換的字符為止,如果不符合“轉換符”的數(shù)據(jù)為空格或者tab則舍掉空格或者tab使文件指針指向下一個數(shù)據(jù)。然后fscanf()繼續(xù)在文件中匹配下一個“轉換符”的數(shù)據(jù)。直到為所有的“轉換符”匹配完數(shù)據(jù)為止。 2.2.2 fscanf()對不符合“特定格式”數(shù)據(jù)的處理當不符合“特定格式”所要求的數(shù)據(jù)且不為空格和tab時,fscanf()將匹配到符合“特定格式”的數(shù)據(jù)賦給地址后不再往下讀。如現(xiàn)將ffReadFile.dat中的內(nèi)容修改如下:Figure3:ffReadFile.dat修改 再用以下代碼讀取第一行數(shù)據(jù), re = fscanf(pF, '%d%d%d', &oLine.p, &oLine.l, &oLine.x);if( 3 == re){ //Print on stdout printf('%d\t%d\t%d\n', oLine.p, oLine.l, oLine.x);}else{ switch(re){ case 1: printf('oLine.p: %d\n', oLine.p); break; case 2: printf('oLine.p: %d, oLine.l: %d\n', oLine.p, oLine.l); break; default: printf('fscanf() read TypeLine error,re: %d\n', re); break;} re的值將是1,從而輸出讀取成功的oLine.p的值。對于此時的情況,只為&oLine.p成功獲取了數(shù)據(jù),另外兩個地址的數(shù)據(jù)都獲取失敗。2.2.3 fscanf()“跳讀符:*”使用‘*’可以跳過文件中的部分內(nèi)容,比如還是圖2中的內(nèi)容,利用以下的語句替換上個程序的fscanf()語句來讀取第一行數(shù)據(jù):re = fscanf(pF, '%d%*3c%d%d', &oLine.p, &oLine.l, &oLine.x); 那么程序的輸出結果為:100 3 2 %*3c表示跳過3個字符內(nèi)容。結合2.1程序就得到了如期的輸出結果。2.2.4 fscanf()與輸入模式相同的讀取如果ffReadFile.dat文件中的內(nèi)容如下,Figure4:ffReadFile.dat 那么如果要讀取文件中的第一行內(nèi)容,書寫以下語句即可: fscanf(pF, '%d,%d,%d', &oLine.p, &oLine.l, &oLine.x); 以上提到的逗號甚至可以換成’a’這樣的字符,但不可以為字符串(Debian Linux 下驗證)。2.2.5 fscanf()讀取指定長度的數(shù)據(jù)針對上圖的文件,可以使用以下語句 fscanf(pF, '%3d,%d,%d', &oLine.p, &oLine.l, &oLine.x); 為&oLine.p讀取只有3位長的數(shù)據(jù),但因為此時文件指針指向10000中最后的那個0使文件中內(nèi)容與fscanf()“format”不再匹配,后兩個地址不能夠正確的獲取數(shù)據(jù)。2.2.6 fscanf()的“format”中的[modifiers]type以上各個小例子已經(jīng)筆記了fscanf的一些特性,它讀數(shù)據(jù)成功與否是看文件中的數(shù)據(jù)是否與format的轉換符相匹配。type就是C語言中的c(字符轉換符), d(整型轉換符符), e、E、f、g、 G(浮點型轉換符), o(八進制類型轉換符), s(字符串類型轉換符), u(無符號整型轉換符), x、X(16進制數(shù)轉換符)轉換符。個人對轉換符的理解是這樣的:將內(nèi)存中的二進制轉換為某種類型,如%d是將存儲到內(nèi)存中的一段二進制轉換為整型數(shù)據(jù)。 modifiers是用來為某些數(shù)據(jù)提供進一步類型轉換用的,比如%d表示將匹配到的數(shù)據(jù)轉換為整型。但在C語言的數(shù)據(jù)類型中還分整型和短整(short int),如果想要將讀取到的數(shù)據(jù)轉換為短整型就需要使用modifiers(‘h’)來進一步表示將匹配到的數(shù)據(jù)轉換為短整型。同理,對于其它可以有進一步分類的數(shù)據(jù)類型也一樣,modifiers提供相應的符號來供數(shù)據(jù)的進一步轉換。Modifiers符號有:
3 使用fscanf()注意的地方確保檢查返回值,以確定找到了期待的值。而使用%s 格式的時候,一定要小心緩沖區(qū)溢出。 CNote Over.
|
|
|