getchar()是在輸入緩沖區(qū)順序讀入一個字符(包括空格、回車和Tab)。
成都創(chuàng)新互聯(lián)是一家專業(yè)提供合江企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、網(wǎng)站制作、H5高端網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為合江眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。
所以你在輸入“12”回車后,“1”首先被讀入,“2”和回車還在輸入緩沖區(qū)里,被后面的getchar()依次讀入。所以有這樣的運行結(jié)果。
這是getchar()使用的不方便的地方。解決方法:
(1)使用下面的語句清除回車:
while(getchar()!='\n');
(2)用getche()或getch()代替getchar(),其作用是從鍵盤讀入一個字符(不用按回車),注意要包含頭文件conio.h
。
/*1.不同點:
scanf不能接受空格、制表符Tab、回車等;
而gets能夠接受空格、制表符Tab和回車等;
2.相同點:
字符串接受結(jié)束后自動加''。
使用scanf("%s",s);函數(shù)輸入字符串時存在一個問題,就是如果輸入了空格會認(rèn)為字符串結(jié)束,空格后的字符將作為下一個輸入項處理,但gets()函數(shù)將接收輸入的整個字符串直到遇到換行為止*/
#include
"stdio.h"
#include
"string.h"
int
l1=0,l2=0;
//l1小寫字母個數(shù),l2大寫字母個數(shù)
main()
{
void
str(char,int);
char
c[100];
int
length;
printf("Please
input
a
string");
/*
scanf("%s",c);*/
gets(c);
length=strlen(c);
str(c,length);
printf("小寫字母個數(shù):%d,大寫字母個數(shù):%d
",l1,l2);
}
void
str(char
b[],int
n)
{
int
i;
for(i=0;in;i++)
if('a'=b[i]b[i]='z')
l1++;
else
if('A'=b[i]b[i]='Z')
l2++;
else
if(b[i]='
')
continue;
}
你看看吧希望能給你幫助
gets()函數(shù)用于從緩沖區(qū)中讀取字符串,其原型如下:
char *gets(char *string);
gets()函數(shù)從流中讀取字符串,直到出現(xiàn)換行符或讀到文件尾為止,最后加上NULL作為字符串結(jié)束。所讀取的字符串暫存在給定的參數(shù)string中。
【返回值】若成功則返回string的指針,否則返回NULL。
注意:由于gets()不檢查字符串string的大小,必須遇到換行符或文件結(jié)尾才會結(jié)束輸入,因此容易造成緩存溢出的安全性問題,導(dǎo)致程序崩潰,可以使用fgets()代替。
擴(kuò)展資料:
功能
從stdio流中讀取字符串,直至接受到換行符或EOF時停止,并將讀取的結(jié)果存放在buffer指針?biāo)赶虻淖址麛?shù)組中。換行符不作為讀取串的內(nèi)容,讀取的換行符被轉(zhuǎn)換為‘\0’空字符,并由此來結(jié)束字符串。
返回值
讀入成功,返回與參數(shù)buffer相同的指針;讀入過程中遇到EOF(End-of-File)或發(fā)生錯誤,返回NULL指針。所以在遇到返回值為NULL的情況,要用ferror或feof函數(shù)檢查是發(fā)生錯誤還是遇到EOF。
注意
本函數(shù)可以無限讀取,不會判斷上限,所以程序員應(yīng)該確保buffer的空間足夠大,以便在執(zhí)行讀操作時不發(fā)生溢出。如果溢出,多出來的字符將被寫入到堆棧中,這就覆蓋了堆棧原先的內(nèi)容,破壞一個或多個不相關(guān)變量的值。
這個事實導(dǎo)致gets函數(shù)只適用于玩具程序,為了避免這種情況,我們可以用fgets(stdin) (fgets實際上可以讀取標(biāo)準(zhǔn)輸入(即大多數(shù)情況下的鍵盤輸入),具體參閱fgets詞條)來替換gets()。在V7的手冊(1979年)中說明:為了向后兼容,gets刪除換行符,gets并不將換行符存入緩沖區(qū)。
參考資料:百度百科-gets
在前面從鍵盤輸入字符串是使用 scanf 和 %s。其實還有更簡單的方法,即使用 gets() 函數(shù)。該函數(shù)的原型為:
# include stdio.h
char *gets(char *str);
這個函數(shù)很簡單,只有一個參數(shù)。參數(shù)類型為 char* 型,即 str 可以是一個字符指針變量名,也可以是一個字符數(shù)組名。gets() 函數(shù)的功能是從輸入緩沖區(qū)中讀取一個字符串存儲到字符指針變量 str 所指向的內(nèi)存空間。
下面將前面中使用 scanf 輸入字符串的程序改一下:
# include stdio.h
int main(void)
{
char str[20] = "\0";? //字符數(shù)組初始化\0
printf("請輸入字符串:");
gets(str);
printf("%s\n", str);
return 0;
}
輸出結(jié)果是:
請輸入字符串:i love you
i love you
擴(kuò)展資料:
從stdin流中讀取字符串,直至接受到換行符或EOF時停止,并將讀取的結(jié)果存放在buffer指針?biāo)赶虻淖址麛?shù)組中。換行符不作為讀取串的內(nèi)容,讀取的換行符被轉(zhuǎn)換為‘\0’空字符,并由此來結(jié)束字符串。
讀入成功,返回與參數(shù)buffer相同的指針;
讀入過程中遇到EOF(End-of-File)或發(fā)生錯誤,返回NULL指針。所以在遇到返回值為NULL的情況,要用ferror或feof函數(shù)檢查是發(fā)生錯誤還是遇到EOF。
參考資料來源:百度百科-gets
是的,如果這是某書上的做法,那么,我只能說它為你們提供了一個錯誤的榜樣。
這樣使用gets()已經(jīng)發(fā)生了溢出!這是gets()不檢查數(shù)據(jù)邊界的bug造成的。
另外,“字符串不是總是以'\0'作為串的結(jié)束符”,答案是肯定的,不然puts()函數(shù)就不能在合適的地方停下來了。這里st[15]被gets()函數(shù)賦值為'\0'。這里要說明的是st[15],st[16]是存在而不合法的,因為字符串實際上就等同于指針,類似st[16]是實在的地址但是是不應(yīng)該被引用的。
為什么這里溢出沒有產(chǎn)生錯誤?可能系統(tǒng)分配內(nèi)存是以一個最小的大小整段整段的分配(這個我只是猜測)。你可以試著輸入的字符串變長一點,就可以看到內(nèi)存讀寫出錯的提示了,這就是溢出的嚴(yán)重后果!我在DOS系統(tǒng)下測試字符串長了直接當(dāng)機(jī)。
驗證1:st[15]被賦值為'\0'
#include"stdio.h"
main()
{
charst[15];
printf("inputstring:");
gets(st);
puts(st);
printf("%d",st[15]);
getch();
}
驗證2:
#include"stdio.h"
main()
{
charst[15];
printf("inputstring:");
gets(st);
puts(st);
//printf("%d",st[16]);
st[1]='\0';
printf("%s\n",st);
printf("%s",st+2);
getch();
}
同樣的建議:拒絕gets(),這本來就是一個有bug的函數(shù)!