[精讚] [會員登入]
1035

【C】(%c, %d)解決讀取字元時的緩衝區殘留

不解決就會莫名其妙地冒出一些莫名其妙的東西

分享此文連結 //n.sfs.tw/15982

分享連結 【C】(%c, %d)解決讀取字元時的緩衝區殘留@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2022-11-16 21:28:17 最後編修
2022-11-16 18:32:27 By 過路君子
 

哈囉大家好,這裡是回歸初心的小編過路君子

從 C 開始學怎麼寫程式,卻已經快要兩年沒有寫任何一個 C 的程式碼......

 

 

在小編那時學 C 的時候程度還不夠,所以沒有要將讀取到的資料餵入陣列的問題,直到最近才突然要寫 C 且遇到這個問題。

所以首先就要來看看小編要讀取的資料格式:

5
X . . P .
. . . . .
P . . . .
. . . . .
. . . . P

第一行會輸入一個數字 n,表示接下來會輸入一個 n * n 的陣列。

而接下來的 n 列資料都是該陣列的資料,以空格和換行做區隔。

 

所以小編採用了以下的策略來讀取資料:

1. 先用scanf("%d", &n)讀取第一個 n 來獲得接下來有多少資料要讀。
2. 緊接著使用 for 迴圈搭配scanf("%c", &ch)來讀取所有的陣列資料。

相關程式碼如下:

#include<stdio.h>
#include<stdlib.h>


int main()
{
	int n;
	scanf("%d", &n);
	
	char **data = malloc(n * sizeof(char*));
	for(int x=0; n>x; x++) 
	{
		char *temp = malloc(sizeof(char));
		*(data + x) = malloc(n * sizeof(char));
		
		for(int y=0; n>y; y++)
		{
			scanf("%c", temp);
			*(*(data + x) + y) = *temp;
		}

		free(temp);
	}

	for(int x=0; n>x; x++) free(*(data+x));
	free(data);
	return 0;
}

結果陣列內的資料內容如下:

X .
. P .

. .
. . .

P .

疑似將換行和空白都當作一般字元來處理,並且丟到陣列裡面了。

 

後來查詢了相關的資料,C 中的 %c 並不會像 %d 一樣會自動忽略空格,空格會被當成一個字元來處理。

所以將第 18 行的 scanf 改成以下:scanf("%c ", temp);

修改後再次讀取資料,結果陣列內的資料內容如下:


X..P
.....
.P...
.....
.....

看似正常了,其實不然。

首先,多了一個奇怪的換行且有一筆資料不見了,原因顯而易見。

 

這就讓小編很難辦了,第一個想到的問題是緩衝區還留著上次讀取數字時的 \n。

但是如果使用 getchar 嘗試去清空緩衝區,那當最後一筆資料進入之後,程式並不停止讀取資料

要再多給一筆才會停止讀取,然後顯示出正常的結果。

 

結果就到處亂鑽,始終沒有找到好辦法來解決這個問題。

直到讀到了某篇文章提到空格和換行之類的對 scanf 是同樣的東西,小編才突然領悟,使否能使用這個特性來清除緩衝區並在正確的時間點停止?

心動不如法上行動,作法也很簡單,直接將第 18 行再改成如下:scanf(" %c", temp);

 

再次啟動程式並未入資料,觀察陣列內的資料:

X..P.
.....
P....
.....
....P

完美!問題解決,花了一個小時就因為空格放錯地方。

 

 

 

後記

真的是好久沒有寫 C 了,難得回來寫一下,沒想到剛寫就踢到鐵板。

有必要玩這麼刺激嗎......

END

你可能感興趣的文章

【C++】一些好用的C++小功能 —— 貳 承襲上一篇的C++小功能,筆記下來以免自己以後忘記了。

【Docker&Wildfly】(bitnami/wildfly)如何從零開始創建網頁伺服器 使用他人的 docker image 來架設我們的 wildfly web server

【Discord bot】[botton]按鈕的使用、響應和關閉 Discord的botton通常都要和View配合使用。

【Wicket】[CSP] Content-Security-Policy & Content-Security-Policy-Report-Only Wicket 預設開啟的,所以如果要加載外部資源甚至是同源資源都會被擋下。

【Linux】網路測速 network speed test 在沒有 GUI 的狀態之下,該如何進行簡單的網路測速呢?

【Kali Linux】[history -c]如何清除歷史記錄 非bash環境會使history部分功能變的非法

隨機好文

高捷少女:美麗島的守護者② 這是在亦晨離開前的下午拍的,當時亦晨在美麗島跟小穹艾米等人在美麗島散步,為離開前補充一些回憶,這時剛好經過的小雅被艾米抓過來,做為同樣是高捷新人的她倆一同拍了一張紀念照。說起來她跟亦晨並不太熟,不過也

婕兒──她的青春④ 「投降吧,耐耐!這回合妳將不會再有獲勝的機會了!哈哈哈哈!」 「妳確定?」耐耐臉上泛起一絲微笑,並將手中的牌展示給婕兒看 婕兒的笑容僵住了。恐懼浮現在她的臉。

【歌評】蓮台野夜行 -古の冥界寺 古老的冥界寺 冥界?那是什麼地方?該不會是像地獄那樣的地方吧?!

【歌評】蓮台野夜行 - 少女秘封倶楽部 少女秘封俱樂部 我們的主角終於出場啦!這首歌一反蓮台野夜行的固有風格,總是華麗的開始又華麗的結束!

【日翻中歌詞】LOSER 一如往常的孤身一人 早就已經被折磨殆盡 明明就已經無處可去 卻作著白日夢 晚安 無論何時都是這個樣子 對懵懂夜晚早感到噁心