fscanf_s與scanf_s的寬度參數與緩沖區參數分析


fscanf_s函數 

在文件操作中經常會用到fscanf這個函數,但是在VC和VS中會有警告

意思是編譯器覺得fscanf不安全,叫你考慮用一下fscanf_s這個函數來代替fscanf,fscanf_s比fscanf多使用了一個參數

fscanf函數原型:

int fscanf( FILE *stream, const char *format [, argument ]...

 

fscanf_s函數原型:

int fscanf_s( FILE *stream, const char *format [, argument ]...

 

fscanf_s的第四個參數是最多讀取的字符數(注意:這個最多讀取的字符數的大小是包括的末尾的('\0')NULL的),下面我們來簡單測試一下第四個參數,先上代碼:

FILE *fp; char ss[10]; fp = fopen("E:\\ww.txt", "r+"); fscanf_s(fp , "%s", ss, 10); printf("%s", ss);

 ww.txt文件中的內容為

運行結果為:

第四個參數10指的是最多讀取的字符數,是包含了字符串末尾的'\0'的,所以實際上最多可以讀取的字符只有10-1=9個字符,如果讀取的字符串長度大於9,那么fscanf_s不會向ss數組中讀入任何內容,只

將數組第一個元素賦值為'\0',下面來測試一下

將ww.txt中的內容改為

運行結果:

可以使用斷點調試來觀察數組ss的的值

還有一點必須要注意,第四個參數是無符號類型的

意思是:0 <= 第四個參數 <= 數組的長度,意思是下面這種寫法是不允許的

char ss[10]; fscanf_s(fp , "%s", ss, 11);

編譯階段不會報錯,但是無法運行(無論讀取內容的是否大於緩沖區大小

 

在微軟的官方手冊中有這樣一段話

當輸入的數據太大時,除非指定了寬度的大小否則不會向緩沖區寫入任何數據

意思是有一種方法可以讓fscanf_s在讀取超過最多讀取的字符數的內容時,仍然只讀取指定了寬度大小的數據,方法如下

fscanf_s(fp , "%5s", ss, 10);

 

與上面不同的是,我們在格式控制符%s這個加了一個寬度控制,意思是最多讀取5個字符

此時ww.txt的內容為明顯文本文件的字符數大於了10,但是由於我們加了寬度控制,fscanf_s仍然會讀取5個字符到ss數組中

運行效果:

 

scanf_s函數

 scanf_s的第四個參數也是最多讀取的字符數,這和fscanf_s完全一樣這里就不再贅述了,讀者可以看一微軟官方文檔中對buffer size的描述

重點:一、buffer size包括了末尾的NULL          

   二、buffer size參數描述的允許讀取的最大的字符數,而不是字節數

因為是最大的字符數,建議在使用這個參數的時候使用_countof這個宏,而不是sizeof,在對char類型的數組限制最大字符數時sizeof和_countof都可以,但是在對寬字符wchar_t類型的數組使用時就不能使用sizeof了,

應該用_countof,最好在前面加上(unsigned)強制轉換為無符號數

 

_countof

_countof是定義在stdlib.h中的一個宏

_countof作用是計算靜態數組中的元素個數,常見的使用方法如下

1 char ss[10]; 2 scanf_s("%s", ss, (unsigned)_countof(ss));

如果對指針使用_countof,則會產生錯誤的結果,因為數組在作為參數傳遞時會退化為指針,這意味着在函數內部不能直接使用_countof來得到數組中元素的個數

 

補充:對於fscanf_s中第四個參數以及寬度控制參數的測試

1、無寬度控制,有緩沖區控制

1 char ss[10]; 2 fscanf_s(fp, "%s", ss, (unsigned)_countof(ss));

 

2、有寬度控制,有緩沖區控制

寬度控制大小 < 緩沖區大小

char ss[10]; fscanf_s(fp, "%5s", ss, (unsigned)_countof(ss));

 

寬度控制大小 = 緩沖區大小

char ss[10]; fscanf_s(fp, "%10s", ss, (unsigned)_countof(ss));

 

寬度控制大小 > 緩沖區大小

char ss[10]; fscanf_s(fp, "%12s", ss, (unsigned)_countof(ss));

 

測試結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM