#include<stdio.h> #include<string.h> void main() { void swap(char*, char*); char str1[40], str2[40], str3[40]; printf("input three line:\n"); gets(str1); gets(str2); gets(str3); if (strcmp(str1, str2) > 0) swap(str1, str2); if (strcmp(str1, str3) > 0) swap(str1, str3); if (strcmp(str2, str3) > 0) swap(str2, str3); printf("Now,the order is:\n"); printf("%s\n%s\n%s\n", str1, str2, str3); } void swap(char *p1, char *p2) { char p[40]; strcpy(p, p1); strcpy(p1, p2); strcpy(p2, p); }
①緣由是Visual C++ 2012 使用了更加安全的 run-time library routines 。新的Security CRT functions(就是那些帶有「_s」後綴的函數);數組
首先,這個問題發生的緣由是您使用了一個不安全的CRT函數,舊式的scanf在讀取數據的時候會根據format指示從緩衝區中讀取直至結束,但有些時候咱們的format指示會有Bug,致使scanf讀取了給定的緩衝區之外(數組越界)的數據。看下例安全
int a = 0;
scanf("%d", &a);
假設咱們輸入數字123456,而後按回車。緩衝區中應該是一個數組123456,加上一個換行符,一般是"\r\n"。
這時候咱們能夠正常地讀取到數字a。
但「有些時候」,緩衝區中的數據並不必定正確,這時候咱們須要限制scanf的讀取範圍,一般是給定緩衝區的起始位置和緩衝區的長度。這樣能夠安全地處理錯誤數據。
但涉及CRT的人在涉及scanf的時候沒有考慮到這麼多的不安全因素,因此有了安全版本的scanf,級scanf_s,s的意思就是safe,咱們會看到不少_s版本的函數,sprintf_s,vsnprintf_s等等,它們的做用都是同樣的。
總之,帶_s的函數是不帶_s的安全版本,咱們在代碼中應當儘可能使用安全版本。
在VS2005以及之後的VC++中,若是咱們使用了不安全的版本,編譯器會給咱們一條警告,警告的內容就和樓主的同樣。
'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. c:\users\user\documents\visual studio 2013\projects\test\test.cpp 8 1 Test
'scanf':這個函數/變量多是不安全的,考慮使用scanf_s來替換它。若是要想忽略這樣警告,請使用宏_CRT_SECURE_NO_WARNINGS。
另外,若是執意要使用不安全的版本而要忽略安全版本,請使用宏_CRT_SECURE_NO_DEPRECATE。
最後,樓主的C4996變成了error,貌似是選中了「將警告視爲錯誤」的編譯選項或者在使用COM開發吧。
ide
②下面給出這個問題的解決方案:函數
方法一:將原來的舊函數替換成新的 Security CRT functions。post
方法二:用如下方法屏蔽這個警告:spa
1. 在預編譯頭文件stdafx.h裏(注意:必定要在沒有include任何頭文件以前)定義下面的宏:code
#define _CRT_SECURE_NO_DEPRECATEorm
2. 或聲明 #param warning(disable:4996)three
3. 更改預處理定義:內存
項目->屬性->配置屬性->C/C++ -> 預處理器 -> 預處理器定義,增長:
_CRT_SECURE_NO_DEPRECATE
方法三:方法二沒有使用更加安全的 CRT 函數,顯然不是一個值得推薦的好方法,但咱們又不想一個一個地改函數名,這裏還有一個更簡便的方法:
在預編譯頭文件 stdafx.h 裏(一樣要在沒有include任何頭文件以前)定義下面的宏:
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
在連接的時候便會自動將舊函數替換成 Security CRT functions 。
注意:這個方法雖然使用了新的函數,可是不能消除警告(緣由見紅字),你還得同時使用方法二(-_-)。即實際應在預編譯頭文件 stdafx.h 里加入下面兩句:
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
錯誤緣由解釋:
這種微軟的警告,主要由於那些C庫的函數,不少函數內部是不進行參數檢測的(包括越界類的),微軟擔憂使用這些會形成內存異常,因此就改寫了一樣功能的函數,改寫了的函數進行了參數的檢測,使用這些新的函數會更安全和便捷。關於這些改寫的函數你不用專門去記憶,由於編譯器對於每一個函數在給出警告時,都會告訴你相應的安全函數,查看警告信息就能夠獲知,在使用時也再查看一下MSDN詳細瞭解。
方法三:無需加那行代碼,只需在新建項目時取消勾選「SDL檢查」便可。以下圖所示:
用以上方法便可解決。