天天看點

scanf和scanf_s、strcpy和strcpy_s、strncpy、gets

在使用vs的時候,使用scanf和strcpy以及gets函數都會報錯,說這幾個函數存在安全問題。下面來看看到底會出現什麼問題,以及安全的函數該如何寫。

1、scanf和scanf_s

scanf在讀取的時候不檢查邊界,可能造成記憶體通路越界,例如配置設定了5個位元組的空間,但是讀入了7個位元組。

char str[]={'\0'};
scanf("%s",str);
如果輸入為個位元組,那麼後面的都會被寫到别的空間去。
#scanf_s("%s",str,);
最多讀取個位元組,最後一個參數表示緩沖區大小,表示最多讀取多少個位元組。
           

2、strcpy和strcpy_s

strcpy依據源字元串的’\0’作為結束标志的,不檢查目标位置的大小,如果目标不夠就會産生溢出問題。

char str[];
strcpy(str,"hello world");
像這樣就會産生溢出問題
strcpy_s(str,,"hello world");
很奇怪的是列印出來的str居然是hello world,而且這麼用在vs中也會出現錯誤,可以去試試。
第二個參數表示目标緩沖區大小,但又必須大于等于源字元串長度+(結尾放'\0'),是以這個函數隻能完全拷貝源串。要想部分拷貝隻能用strncpy_s。
           

3、strncpy_s

這個函數可以部分拷貝。

char str[];
strncpy_s(str,,"hello world",);
表示從源拷貝個位元組到個位元組的目标空間
           

4、gets

gets不檢查字元串的大小,必須遇到換行符或檔案結尾才會結束輸入,容易造成緩存溢出的安全問題,可以用fgets代替。

char str[];
fgets(str,,stdin);
表示從鍵盤讀入個字元