gets fgets 区别
http://www.cnblogs.com/aexin/p/3908003.html
1. gets與fgets
gets函數(shù)原型:char*gets(char*buffer);//讀取字符到數(shù)組:gets(str);str為數(shù)組名。
gets函數(shù)功能:從鍵盤上輸入字符,直至接受到換行符或EOF時停止,并將讀取的結(jié)果存放在buffer指針?biāo)赶虻淖址麛?shù)組中。
讀取的換行符被轉(zhuǎn)換為null值,做為字符數(shù)組的最后一個字符,來結(jié)束字符串。
注意:gets函數(shù)由于沒有指定輸入字符大小,所以會無限讀取,一旦輸入的字符大于數(shù)組長度,就會發(fā)生內(nèi)存越界,
從而造成程序崩潰或其他數(shù)據(jù)的錯誤。
fgets函數(shù)原型:char *fgets(char *s, int n, FILE *stream);//我們平時可以這么使用:fgets(str, sizeof(str), stdin);
其中str為數(shù)組首地址,sizeof(str)為數(shù)組大小,stdin表示我們從鍵盤輸入數(shù)據(jù)。
fgets函數(shù)功能:從文件指針stream中讀取字符,存到以s為起始地址的空間里,知道讀完N-1個字符,或者讀完一行。
注意:調(diào)用fgets函數(shù)時,最多只能讀入n-1個字符。讀入結(jié)束后,系統(tǒng)將自動在最后加'\0',并以str作為函數(shù)值返回。
2. 細(xì)節(jié)介紹
1,上面說到gets函數(shù)無限讀取,沒有上限。但是有些資料介紹說它最多只能讀取1024個,所以我寫了下面代碼測試一下
?(有興趣的朋友可以測試一下(●'?'●))
1 //測試gets最多讀取字符是否超過1024 2 #include <stdio.h> 3 #include <string.h> 4 5 int main() 6 { 7 char str[2048]; //聽說gets最多可以讀取1024個字符,我們設(shè)定一個2048的數(shù)組 8 gets(str); //從鍵盤輸入大于1024個字符 9 int cnt; 10 printf("cnt = %d", strlen(str)); //cnt的值就是數(shù)組元素個數(shù),是否大于1024呢??? 11 12 return 0; 13 }經(jīng)本人親自測試第一次cnt = 2003,第二次cnt = 2086,第二次程序最后崩潰了,但是不能說明gets的讀取上限為2086左右,
因為程序崩潰是由于內(nèi)存越界
2,在來細(xì)說一下fgeis的用法,我們以char str[N];fgets(str, N, stdin);為例:
fgets只能讀取N-1個字符,包括最后的'\n',讀完結(jié)束后系統(tǒng)將自動在最后加'\0'(gets讀完結(jié)束后系統(tǒng)自動會將'\n'置換成'\0')。
說到這里就有倆種情況了:
一:當(dāng)你從鍵盤上輸入<=N-1個字符(包括'\n')時,那么字符串str會以‘\n\0’結(jié)尾。這就造成了strlen(str)比你想象的大 1 ,
當(dāng)然你可以通過下面代碼將'\n'去掉。
1 if(str[strlen(str) - 1] == '\n') { // 去掉換行符 2 str[strlen(str) - 1] = '\0'; 3 }二:當(dāng)你從鍵盤上輸入>N-1個字符(包括'\n')時,那么字符串str會以'\0'結(jié)尾。
3,在上面我們提到從鍵盤輸入字符大于N的情況,這時gets和fgets就又有一些區(qū)別了,我們通過以下代碼來測試一下:
1 #include <stdio.h> 2 #include <string.h> 3 #define N 5 4 5 int main() 6 { 7 char s1[N]; 8 char s2[N]; 9 fgets(s1, N, stdin); 10 // gets(s1); 11 if(s1[strlen(s1) - 1] == '\n') { // 去掉換行符 12 s1[strlen(s1) - 1] = '\0'; 13 } 14 15 // fflush(stdin); //清空緩沖區(qū) 16 fgets(s2, N, stdin); 17 // gets(s2); 18 if(s2[strlen(s2) - 1] == '\n') { // 去掉換行符 19 s2[strlen(s2) - 1] = '\0'; 20 } 21 22 printf("%s %s", s1, s2); 23 24 return 0; 25 }
當(dāng)我們輸入12345按下回車,直接就出來1234 5這樣的結(jié)果。是不是與我們預(yù)想的不一樣呢?我們單看結(jié)果,s1是1234,
s2是5。這是為什么呢?
這就是fgets與gets的不同之處,我們第一個fgets只讀取了1234,將5'\n'放入緩沖區(qū)中,當(dāng)程序運行到第二個fgets時,
它就會直接從緩沖區(qū)讀取,直到遇到'\n'結(jié)束所以就會有這樣的結(jié)果,此時s1是1234'\0',s2是5'\0'.我們應(yīng)該怎么解決這種問題呢?
我們可以在第二個fgets前加一句fflush(stdin),它是清除緩沖區(qū)的作用,大家可以試試,我就不截圖了。
上面我們是用fgets輸入的,現(xiàn)在我們換成gets來輸入,看看結(jié)果吧:
說到這里就已經(jīng)不是簡單的gets與fgets的問題了,這涉及到了我們從鍵盤讀入的數(shù)據(jù)在內(nèi)存中是怎么顯示的了,所以我只簡單的說一下。
在內(nèi)存中s1是這樣排序的
?
| '\0' |
| 6 ? |
| 5 |
| 4? |
| 3? |
| 2? |
| 1 |
當(dāng)s2輸入進(jìn)來的時候會變成:
| ?'\0' |
| 6 |
| 5 |
| 4 |
| 3 |
| ?'\0' |
| f |
| e |
| d |
| c |
| b |
| a |
所以輸出的時候就會s1輸出f,后遇'\0'結(jié)束,s2輸出abcdef,后遇'\0'結(jié)束。
總結(jié)
以上是生活随笔為你收集整理的gets fgets 区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。