字符數組 的英文名字是 char []
gets()函數的基本用法為:
char *gets(char *s);
該函數的參數是一個字符數組,該函數的返回值也是一個字符數組。
linux下的代碼如下:
1 #include <stdio.h>
2
3 int main()
4 {
5 char a[100] = { 0 };
6 gets(a);
7 printf("%s\n", a);
8 return 0;
9 }
-----------------------------------------------------------------------------
編譯時會出現一個warning,建議我們不要使用gets函數了。我們暫時不管他,先直接運行看結果。
--------------------------------------
警告如下:
a2.c:6:5: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
gets(a);
^
/tmp/cceyMQ7u.o: In function `main':
a2.c:(.text+0x41): warning: the `gets' function is dangerous and should not be used.
--------------------------------------
原因:
問題出在程序中使用了 gets是非常不安全的。這是對程序產生BUG,出現不可靠性的一個描述,有些函數在某些意外情況會導致程序陷入不可控狀態,僅僅是PC上運行最多也就是退出而已,但是如果是運行在飛機等系統里的話,就會有大麻煩,說危險也不為過。因為英文文獻里描述為dangerous,所以也就翻譯為危險。
函數執行需要一個棧空間,但這個棧空間容量是有限的,而且棧里存放了函數返回的地址。gets()函數在獲取輸入時,如果無限輸入會造成棧空間溢出,在程序返回時,不能正常的找到返回地址,程序將發生不可預測行為。
--------------------------------------
解決:
解決辦法是使用 fgets,但由於fgets函數是為讀取文件設計的,所以讀取鍵盤是沒有gets那么方便。
fgets()函數的基本用法為:
fgets(char *s, int size, FILE *stream);
第一個參數是:字符類型的數組,第二個參數是:標明這個數組的大小,第三個參數是:如果總是通過鍵盤輸入的話,可以固定寫為stdin。
--------------------------------------
示例程序:
/*代碼實現01_使用fputs函數打印輸出*/
#include <stdio.h>
int main ( ) {
char name[20] = { 0 };
fgets(name, sizeof(name), stdin); //stdin 意思是鍵盤輸入
fputs(name, stdout); //stdout 意思是通過打印設備輸出
return 0;
}
--------------------------------------
/*代碼實現02_使用printf函數打印輸出*/
#include <stdio.h>
int main ( ) {
char name[20] = { 0 };
fgets(name, sizeof(name), stdin); //stdin 意思是鍵盤輸入
printf("%s", name); //這邊輸出不需要 \n 了,實際操作時,fgets會認為用戶輸入的回車也是字符串的一部分內容。即輸出的內容中間接地帶了 \n 了。
return 0;
}
-----------------------------------------------------------------------------
fgets會認為用戶輸入的回車也是字符串的一部分內容。
fgets是安全的,不會因為用戶惡意的輸入過長的字符串導致溢出。因為它只接受它能存的最大的字符數,其余的舍掉!