2010-06-24 58 views
7

區別,我在行爲下列區別不解:的fscanf/fscanf_s行爲

// suppose myfile.txt contains a single line with the single character 's' 
    errno_t res; 
    FILE* fp; 
    char cmd[81]; 

    res = fopen_s(&fp, "D:\\myfile.txt", "rb"); 
    fscanf(fp,"%80s",cmd); // cmd now contains 's/0' 
    fclose(fp); 

    res = fopen_s(&fp, "D:\\myfile.txt", "rb"); 
    fscanf_s(fp,"%80s",cmd); // cmd now contains '/0' ! 
    fclose(fp); 

結果不依賴於呼叫的順序(即,首先調用fscanf_s,你會得到空字符串第一)。編譯在VC++ - VS2005上。任何人都可以重現?誰能解釋一下?

謝謝!

回答

8

從文檔上fscanf_s()http://msdn.microsoft.com/en-us/library/6ybhk9kc.aspx

的安全功能(帶_s後綴)和較早的功能之間的主要區別是,安全功能要求每個c,C,s,S和[type字段的大小作爲參數立即傳遞給變量。有關更多信息,請參閱scanf_s,_scanf_s_l,wscanf_s,_wscanf_s_l和scanf寬度規範。

而且http://msdn.microsoft.com/en-us/library/w40768et.aspx

不同於scanf函數和wscanf,scanf_s和wscanf_s需要鍵入c,C,S,S,或[的所有輸入參數中指定的緩衝區大小。緩衝區大小作爲附加參數在指向緩衝區或變量的指針之後立即傳遞。例如,如果讀取一個字符串,該字符串的緩衝區大小如下傳遞:

char s [10];

scanf(「%9s」,s,10);

所以你應該把它像這樣:

fscanf_s(fp,"%80s",cmd, sizeof(cmd)); 
6

fscanf_s(和整個家庭scanf_s)要求您傳遞的大小任意%c%C%s%S,或緩衝區本身後%[;你忽略這樣的說法:

fscanf_s(fp, "%80s", cmd, 81); 
+3

這看起來好像是錯誤的用法。 '81'應該是'cmd'緩衝區的大小。但是嗎?即使使用「安全」功能,這也是編寫崩潰代碼的好方法。在讀入靜態字符數組時,應該有'sizeof(cmd)',一些變量存儲緩衝區被分配的長度,或者調用給定緩衝區的大小/容量函數。雖然你的例子在技術上是正確的,但它可能會讓很多人誤解。 – 2013-09-02 13:04:51

2

你的問題被標記C++和你在編譯VC++,但使用的fscanf?獲取一個std :: ifstream。

std::string buffer; 
std::ifstream fp("my filepath"); 
fp >> buffer;