標(biāo)準(zhǔn)I/O庫函數(shù):fgets與gets比較分析
函數(shù)名:fgets
功能:從流中讀取一個字符串
用法:char *fgets(char *string,int n,FILE *stream);
形參注釋:
*string:結(jié)果數(shù)據(jù)的首地址;n-1:一次讀入數(shù)據(jù)塊的長度,其默認(rèn)值為1k,即1024;stream文件指針,指向一個文件
函數(shù)說明:
fgets()用來從參數(shù)stream所指的文件內(nèi)讀入字符并存到參數(shù)s所指的內(nèi)存空間,直到出現(xiàn)換行字符、讀到文件尾或是已讀了size-1個字符為止,最后會加上NULL作為字符串結(jié)束。
如果在未讀滿n-1個字符之時,已讀到一個換行符或一個EOF(文件結(jié)束標(biāo)志),則結(jié)束本次讀操作,讀入的字符串中最后包含讀到的換行符。
示例:
#include <string.h>
#include <stdio.h>
int main(void)
{
FILE *stream; //FILE 是一種數(shù)據(jù)類型,是管理文件流的一種結(jié)構(gòu)
char string[] = "This is a test";
char msg[20];
/* open a file for update */
stream = fopen("DUMMY.FIL", "w+");
/* write a string into the file */
fwrite(string, strlen(string), 1, stream);
/* seek to the start of the file */
fseek(stream, 0, SEEK_SET);
/* read a string from the file */
fgets(msg, strlen(string)+1, stream);
/* display the string */
printf("%s", msg);
fclose(stream);
return 0;
}
代碼分析:
操作成功時返回的是msg的值,如果碰到文件結(jié)束或錯誤的時候,fgets返回NULL;因?yàn)檩斎氲倪^程中一般只會按下回車,很少會是EOF的,所以不會是碰到文件結(jié)束,而錯誤是當(dāng)你傳入msg是NULL的時候才會遇到,所以基本上是不可能返回NULL的。而且輸入超過了長度n的時候,fgets會自動截斷的,屬于操作成功。
函數(shù)名:gets
功能:從stdin流中讀取字符串,直至接受到換行符或EOF時停止,并將讀取的結(jié)果存放在str指針?biāo)赶虻淖址麛?shù)組中。換行符不作為讀取串的內(nèi)容,讀取的換行符被轉(zhuǎn)換為null值,并由此來結(jié)束字符串。
示例:
#include"stdio.h"
void main()
{
char str1[5];
gets(str1);
printf("%sn",str1);
}
注意:本函數(shù)可以無限讀取,不會判斷上限,所以程序員應(yīng)該確保str的空間足夠大,以便在執(zhí)行讀操作時不發(fā)生溢出。
代碼分析:
用gets函數(shù)時,編譯器會有報警提示,因?yàn)間ets函數(shù)不安全,沒有限制輸入緩沖區(qū)的大小,容易造成溢出。這就好像養(yǎng)金魚,你投多少魚食它就吃多少,自己不知道控制,但它的胃容量是有上限的(默認(rèn)值),喂的太多金魚就會撐死(溢出)。
總結(jié):
1 盡量不使用gets
2 內(nèi)存越界是有問題隱患,但并不是一定會體現(xiàn)出問題,要看具體情況。
來源:miaomi2次