C/C++進階筆記(一)

blog date : 2015-12-19

對於C/C++語言相關的知識目前藉助的是《C語言大學教程》這本書,後面就是零散的記錄一些知識和問題,如果有大塊的內容再做系統的分析和記錄。

1,對於#define的認識,#define是程序編譯時預處理的步驟,這時候還沒有進入正式編譯,對於#define來講他的行爲是進行文本的替換,也就是說在後續編譯的時候將define的宏文本進行替換然後進行編譯,這也就是爲什麼在#define後加分號時,會報語句不完整的錯誤,因爲相當於在代碼中間多了一個分號;

2,關於scanf和鍵盤緩衝區的問題,這個可能寫的會稍微長一些。

scanf在C中不能輸入空格、TAB、換行、EOF等字符,在輸入這些字符之後會退出函數,那麼如果要用scanf支持空格輸入怎麼辦呢,我在網上找到了一個辦法是scanf("%[^\n]",str),這裏用到了一個類似正則表達式的東西^,表示如果不接受\n,那麼在敲入回車之後纔會退出scanf函數,於是我寫了下面這個小程序來驗證:

int main()
{
	char string1[100];
	
	while(1){
		scanf("%[^\n]",string1);

		printf("%s\n",string1);
	}
	return 0;
}

這時候就出現了問題,在第一次輸入"hello world"之後,後面就開始被hello world刷屏了,這應該是鍵盤緩衝區的問題,如果用fflush(stdin);或者rewind(stdin);清除鍵盤緩衝區就可以解決這個問題,每次輸入、然後printf輸入字符串後,可以進行下一次鍵盤輸入。但是到底鍵盤緩衝區出了什麼問題我很好奇,於是我做了如下的測試:

int main()
{
	char string1[100];
	char str;
	int temp;
	
	while(1){
		//rewind(stdin); 
		//fflush(stdin);
		temp = scanf("%[^\n]",string1);
		str = getchar();

		printf("%s\n",string1);
	}
	return 0;
}

發現scanf之後getchar是一個換行符,而如果沒有這個getchar循環的第二次以後temp都是0,意味着鍵盤緩衝區在第一次scanf之後留下了一個\n,這個在下一次循環scanf的時候遇到\n停止認爲什麼都沒讀到,然後繼續。這說明用scanf("%[^\n]",str)最後的\n不會像scanf("%s",str)那樣把空格、換行清掉。

對於這個問題還可以用如下方式解決scanf("%[^\n]%*c",str),%*c相當於忽略後面的字符,這時候就會把\n清掉,鍵盤緩衝區就不再有其他無用字符了。感覺這個scanf和getchar還是有關係的,不知道是不是scanf就是用getchar實現的,這也算一個小bug吧。這表明在使用鍵盤輸入的時候還是要多做清除鍵盤緩衝區的處理,這樣可以保證程序的健壯性和安全性。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章