當前位置:編程學習大全網 - 源碼下載 - C語,scanf出錯了,不知道怎麽回事

C語,scanf出錯了,不知道怎麽回事

轉載自:

網頁鏈接

VS中”This function or variable may be unsafe.”警告的解決辦法

問題原因

C語言的標準函數中,壹些讀取或寫入內存的函數存在內存越界的問題,從而使得內存數據變得不安全。如scanf、gets、strcat等函數都存在著這樣的問題。

為了避免這個問題,在VS中,另外提供了如scanf_s,get_s,strcat_s等相關的改進函數,來替代原來的標準函數的功能,並通過添加內存讀取範圍的限制來解決不安全的問題。

在實際的應用中,也許使用VS提供的安全函數會更加合理。但是,在學習中,幾乎所有的課本以及教程都使用的原來的標準函數,另外考慮到移植性的問題,除了VS環境,其他環境中並沒有提供改進後的函數。因此,我們通常任然需要標準的庫函數來實現相關功能。

但是,如果在VS中使用原始的函數,編譯器將會報錯。這對使用和學習都帶來了相當的不變。

問題分析

在VS2013中,以scanf為例。

如果在程序中使用了scanf函數,如下

#include <stdio.h>

int main()

{

char c[20];

scanf("%s", c);

puts(c);

return 0;

}

1

2

3

4

5

6

7

8

編譯將得到如下錯誤信息。

error C4996: ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

參見“scanf”的聲明

錯誤信息的大意如下

此函數或變量可能不安全。

可以使用scanf_s代替該函數。

如果要取消禁用,請定義_CRT_SECURE_NO_WARNINGS。

更多信息請查看在線幫助

scanf的聲明如下

_Check_return_ _CRT_INSECURE_DEPRECATE(scanf_s) _CRTIMP int __cdecl scanf(_In_z_ _Scanf_format_string_ const char * _Format, ...);

1

在scanf的聲明中,在函數的標準形式說明之前,還用到了幾個宏定義,正是因為這幾個宏定義才實現了scanf函數的禁用。

在VS中利用F12可以看到這幾個宏的定義,宏定義具體內容如下

sal.h

#define _Check_return_ _SAL2_Source_(_Check_return_, (), _Check_return_impl_)

crtdefs.h?

#define _CRT_INSECURE_DEPRECATE(_Replacement) _CRT_DEPRECATE_TEXT("This function or variable may be unsafe. Consider using " #_Replacement " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.")

crtdefs.h?

#define _CRTIMP __declspec(dllimport)

1

2

3

4

5

6

7

8

上面三個宏都包含了宏的嵌套調用,相關宏略多,因此在此不對其進行深入研究。

不過在第二個宏定義中,我們可以很容易發現在編譯時,編譯器向我們返回的錯誤信息。這進壹步說明了scanf函數不能使用與這幾個宏有關。

問題解決

在編譯器給出的錯誤提示中,實際上已經為我們給出了壹個明確的解決方案。我們只需要在程序的開頭添加壹個宏定義便能夠解決問題。

#define _CRT_SECURE_NO_WARNINGS

1

加入宏定義後,源代碼變為如下形式

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main()

{

char c[20];

scanf("%s", c);

puts(c);

return 0;

}

1

2

3

4

5

6

7

8

9

再次進行編譯,編譯成功完成。

雖然按照上述的方法能夠順利解決問題,但是在實際的應用中,如果我們要求只能夠使用標準庫中的函數,而不能使用VS為我們提供的改進函數。那麽我們每次在使用到相關函數時,都需要在文件前面,或者在頭文件中添加相關宏。這樣未免太麻煩。

既然我們不需要VS給我們提供的這個多余的改變,那有沒有壹個壹勞永逸的辦法解決這個問題呢。

方法是有的,這需要我們對VS的項目屬性進行設置,具體步驟如下。

在項目屬性設置中找到選項卡配置屬性→C/C++→預處理器;

在右側的參數中找到預處理器定義,編輯其參數;

在參數的末尾添加定義_CRT_SECURE_NO_WARNINGS

這樣,在編譯器進行預處理時,預處理器就會自動在程序開頭添加我們需要的宏定義,而不再需要我們手動添加。

在文件中不添加宏定義的情況下,再次進行編譯。發現編譯順利完成。

這種方案因為修改的是項目的配置參數,因此適用於整個項目。在該項目中,將不再需要添加相關宏定義。但是其他項目自然不受該設置的影響,因此,如有需要,在其他項目中需要再次進行相同配置才能生效。

————————————————

版權聲明:本文為CSDN博主「夏蒼」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:/u012534008/java/article/details/54602774

  • 上一篇:帶時間窗的貨物配送問題
  • 下一篇:戴蓮。com源代碼
  • copyright 2024編程學習大全網