gets()getchar()與緩衝區的問題

飛翔的黃瓜發表於2017-08-23

今天做一道演算法題時,遇到可這樣的問題

#include "stdafx.h"
#include "iostream"
#include "string"
int main()
{
	int num=0;
	char a[100];
	std::cin>>num;//這裡輸入完成後,會直接進入迴圈執行一次
	std::cout<<std::flush;
	//std::cin.clear();
	//std::cin.sync();
	for(int i=0;i<num;i++)
	{
		gets(a);//按道理進了迴圈這裡應該等待輸入的,卻執行了一次才等待輸入
		std::cout<<a<<std::endl;
	}
}

想了一下,是緩衝區的問題,cin在讀取數字之後,會遺留一個換行符'\n'在緩衝區,而gets(getchar也一樣)會先對緩衝區進行查詢,讀到了'\n'後就拿來讀入了,造成這樣的後果,這裡加上clear()和sync()清除緩衝區後正常,(ps:這兩個必須同時呼叫才有作用,不太明白。另外,我在這裡加cout<<flush卻沒有作用,可能flush只能用於清空輸出時候的快取?)

這裡用一下別人對scanf get等的解釋

Scanf()函式讀取數字,字元,字串的時候,都會遺留一個換行符在緩衝區,但是它不讀取換行符(輸入數字時空白符都不讀),因為不讀所以遺留在了緩衝區。getchar()會讀取緩衝區剩餘的空白符(包括換行符),並且會遺留一個換行符。而gets()會讀取緩衝區空白字元,它讀了換行符,然後丟棄,所以它不會遺留換行符。可以認為使用它之後緩衝區是乾淨的(但是gets會讀取別人留在緩衝區內的換行符並顯示)。fgets和讀區取檔案有關,它也會讀取緩衝區內容。它讀區換行符後,保留它。它之後,緩衝區是乾淨的還是不乾淨的,哦,看引數和輸入。綜上,在scanf下面用其它三個函式時,要清空緩衝區,在getchar下面用除scanf的其它三個函式時(包括它自己拉。),要清空緩衝區,因為Scanf對它免疫。而gets之後用其它三個函式是安全的,而fgets之後是否清空視情況而定。

相關文章