為了避免緩沖區溢出,從終端讀取輸入時應當用fgets()代替gets()函數。
但是這也將帶來一個問題,因為fgets()的調用格式是:
fgets (buf, MAX, fp)
fgets (buf, MAX, stdin)
buf是一個char數組的名稱,MAX是字符串的最大長度,fp是FILE指針。
fgets()函數讀取到它所遇到的第一個換行符的后面,或者讀取比字符串的最大長度少一個的字符,或者讀取到文件結尾。然后fgets()函數向末尾添加一個空字符以構成一個字符串。如果在達到字符最大數目之前讀完一行,它將在字符串的空字符之前添加一個換行符以標識一行結束。
問題出在有時字符串的結尾處可能多出一個換行符,我們需要把它去掉。
#include <stdio.h> #include <string.h> #define LEN 5 int main() { char str[LEN]; fgets(str, LEN, stdin); //fprintf(stderr, "%s %d\n", str, strlen(str)); for(int i = 0; i < LEN; i++) printf("%d\t", str[i]); printf("\n"); if(str[strlen(str)-1] == '\n') str[strlen(str)-1] = '\0'; for(int i = 0; i < LEN; i++) printf("%d\t", str[i]); printf("\n"); return 0; }
輸入:
abc
輸出:
97 98 99 10 0
97 98 99 0 0
說明,當輸入的字符少於指定數目時,會將最后一個換行符保存在s[len-1]的位置,s[len]處恆為'\0'。
輸入:
abcdefg
輸出:
97 98 99 100 0
97 98 99 100 0
說明,當輸入的字符大於指定數目時,保存指定字符串長度-1個字符,不保存換行符,s[len]處恆為'\0'。
也想過用如下的函數來處理:
void clearEnter(char *p) { while(*p) { if(*p == '\n') *p = '\0'; p++; } }
但該函數有個問題,在此處處理fgets()函數獲得的字符串尾的換行是有效的。假如字符串中間不是從fgets()函數獲得,而字符串中間有換行符,則會將字符串中第一個換行符替換為'\0',也就丟棄了字符串的其他部分。