小朋友學C語言(42):gets和fgets
阿新 • • 發佈:2018-11-28
一、gets()函式
原型:char *gets(char *str);
標頭檔案:stdio.h
例1
#include <stdio.h>
int main()
{
char str[10];
gets(str);
puts(str);
return 0;
}
(1)在Windows系統中的執行結果
hello
hello
(2)在Linux中用GCC進行編譯
[email protected]:~/Desktop$ gcc test.c -o test test.c: In function ‘main’: test.c:6:5: warning: ‘gets’ is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations] gets(str); ^ /tmp/cc0hPgqA.o:在函式‘main’中: test.c:(.text+0x1d): 警告: the `gets' function is dangerous and should not be used.
執行結果
[email protected]:~/Desktop$ ./test
hello
hello
例2
#include <stdio.h>
int main(void)
{
char c;
char s[3];
scanf("%c",&c);
getchar(); // 過濾回車
gets(s);
printf("string=%s\nchar=%c\n", s, c);
return 0;
}
執行結果
在windows下輸入:
a
hi
輸出
string=hi char=a
在windows下重新輸入
a
uvwxyz
輸出
string=uvw
char=x
這裡可以看出來,定義了s的長度為3,但是用gets()輸入字串的時候,並不會去檢查字串的長度,所以導致char的值不是a,而是”uvwxyz”中的第四個字元’x’。
不正確使用gets()函式的時候造成的危害是很大的,就像我們剛才看到的那樣,a的值被字串s溢位的值給替換了。
因為gets有不限制輸入字元個數的限制,可能會導致不法分子利用這一漏洞造成緩衝區溢位,從而達到破壞的目的。《C Primer Plus》中提到蠕蟲病毒就是利用這一漏洞來攻擊作業系統。
出於安全考慮,用fgets()來代替gets()。
二、fgets()函式
原型:char * fgets(char * s, int n,FILE *stream);
標頭檔案:stdio.h
fgets()函式讀取到它所遇到的第一個換行符的後面,或者讀取比字串的最大長度少一個的字元,或者讀取到檔案結尾。然後fgets()函式向末尾新增一個空字元以構成一個字串。如果在達到字元最大數目之前讀完一行,它將在字串的空字元之前新增一個換行符以標識一行結束。
例3
#include <stdio.h>
#define len 5
int main()
{
char c;
char s[len];
scanf("%c", &c);
getchar(); // 過濾回車
fgets(s, len, stdin);
printf("string=%s\nchar=%c\n", s, c);
return 0;
}
執行結果
輸入:
a
uvwxyz
輸出:
string=uvwx
char=a
這裡string=uvwx的後面其實還有一個空字元’\0’沒有顯示出來。
例4
#include <stdio.h>
#include <string.h>
#define len 100
int main()
{
// stdin,標準輸入流,預設是鍵盤,重定向到檔案title.in,scanf或fgets從title.in中讀取資料
freopen("title.in", "r", stdin);
// stdout,標準輸出流,預設是顯示器,重定向到title.out,printf把資料寫到title.out中
freopen("title.out", "w", stdout);
char s[len];
fgets(s, len, stdin);
int total = 0;
// 這裡只能用strlen,不能用sizeof
// 因為sizeof(s)=sizeof(s)/sizeof(char)=100
for(int i = 0; i < strlen(s); i++)
{
if(s[i] != ' ')
{
total++;
}
}
printf("%d", total);
return 0;
}
少兒程式設計QQ群:581357582
少兒英語QQ群:952399366