gets()函數 因為用gets函數輸入數組時,只知道數組開始處,不知道數組有多少個元素,輸入字元過長,會導致緩衝區溢出,多餘字元可能占用未使用的記憶體,也可能擦掉程式中的其他數據,後續用fgets函數代替。 fgets函數 一小段代碼舉例: (1) fgets函數一次讀入10 - 1個字元,如果少於 ...
gets()函數
因為用gets函數輸入數組時,只知道數組開始處,不知道數組有多少個元素,輸入字元過長,會導致緩衝區溢出,多餘字元可能占用未使用的記憶體,也可能擦掉程式中的其他數據,後續用fgets函數代替。
fgets函數
一小段代碼舉例:
1 char words[stlen]; 2 fgets(words,10,stdin); 3 fputs (words,stdout); 4 puts(words);
(1) fgets函數一次讀入10 - 1個字元,如果少於這個字元數數按下回車
例如輸入apple pie 則會將apple pie\n\0儲存在數組中
隨後的fputs列印時不添加\n
而puts列印會添加\n,結果會空一行
(2) 一次讀入超過10 - 1個字元則會在讀取apple pie後加\0儲存在數組中
列印時因為沒有\n 函數fputs之後沒有換行,緊接著puts列印
fgets()函數讀到文件結尾會返回一個空指針,代碼可用0代替,或者用NULL //因為暫時不常見在此不做介紹
在11.8中
# include<stdio.h>
# define stlen 10
int main(void)
{
char words[stlen];
while(fgets(words,stlen,stdin) != NULL&&words[0] != '\n')//不斷迴圈把stlen-1字元放在數組中加\0,直到最後結尾為\n\0,
fputs(words,stdout);
puts("done.");
return 0;
}
輸入字元長度超過 10-1 時仍會全部列印,因為輸入緩衝區的原因,輸入aaaaaaaaabbbbbbbbbccccccccc,字元串會在緩衝區暫時保存,第一次while會將aaaaaaaaa輸出但沒有換行,
第二次時bbbbbbbbb,最後的c結束時會將ccccccccc\n\0儲存列印時會換行。
儲存換行符有好處也有壞處,想去除換行符,可以在已知的字元串中查找換行符,
while (words[i] != '\n')
i++;
word[i] = '\0';
如果仍有字元串留在輸入行就用
while(getchar() != '\n')//讀取但不儲存輸入,包括\n
continue;
這樣可以清除緩衝區,超過設定長度會將後面的清除,只列印設定長度字元串。
1 # include<stdio.h>
2 # define stlen 10
3 int main(void)
4 {
5 char words[stlen];
6 int i;
7 while(fgets(words,stlen,stdin) != NULL&&words[0] != '\n')
8 {
9 i = 0;
10 while(words[i] != '\n'&&words[i] != '\0')
11 i++;
12 if(words[i] == '\n')
13 words[i] == '\0';
14 else //也就是words[0] == '\0'時
15 while(getchar() != '\n')
16 continue;
17
18 puts(words);
19
20 }
21 return 0;
22 }
上述代碼,若輸入apple 則輸出apple
若輸入aaaaaaaaabbbbbbb 則輸出aaaaaaaaa 因為在輸入後緩衝區是aaaaaaaaabbbbbbb,讀取規定字元數將aaaaaaaaa\0放在words中,後續代碼檢測到\0
因為getchar()緩衝區的字元b依次被讀取並被丟棄,知道讀取到換行符\n,輸出words // \n 也被丟棄。