[精讚] [會員登入]
949

【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

你可能感興趣的文章

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

【Javascript】(Event)常用的網頁事件 不寫下來絕對下又會忘記,然後每次又都要回到MDN去查,麻煩

【JDA/discord bot】package does not exist fix JDA 4.0 和 5.0 差別還是很大的

【C++】使用SFML製作讓方塊落下的畫面 從開啟新視窗延伸過來的應用(?),配合上一篇所使用到開啟一個可渲染視窗的那堆程式碼的延伸。

【Docker hub】[Linux]以IPv6來pull容器(container)吧! 在一個 IPv6 還不盛行的年代,做事情總是特別麻煩

【C++】使用struct array和一維int array模擬二維int array 主要是因為用sort去排序int array的二維陣列小編懶得研究,於是就研究了一種維持一維陣列但是有二維陣列效果的程式,小編就廢~~

隨機好文

[活動] 2017年4/1雲空幻想愚人節活動彩蛋&攻略 (紀念性質) 雲空幻想2017年的愚人節活動介紹同時也是本小編的第一篇網路文章(*^ω^)♪

高捷少女:購票大作戰① 「各位乘客,本班機即將降落,感謝各位乘客的搭乘……」隨著空中小姐的廣播音,那架飛機逐漸降落在地面,裡面的乘客們也紛紛開始整理自己的行李。 那個有著歐美人五官的少女抓緊包包,看著外面的小港機場,臉上緩緩

高捷少女:購票大作戰② 一個不好的預感浮現,艾米莉亞開始檢查屋子四處。窗戶跟陽台都有關好,也沒有被打開的跡象。但一股無形的壓力,開始在寂靜的公寓中蔓延,她不安地嚥一下喉嚨。最後,她走向那扇窗戶,那前天晚上,白龍為了逃脫,而撞

高捷少女:耐耐的新年驚喜② 「各位,我跟爸媽聊完了……」耐耐走進客廳,看到大家在看自己的相簿,臉蛋立刻紅了。「哇啊啊,不要看那個!」她三步併作兩步地走向少女們,將相簿拿走。「為什麼啊?小時候的耐耐很可愛啊。」婕兒不解地說。

高捷少女:耐耐的新年驚喜③ 即使如此,夫人仍然每年都會問老爺是否能空出一週時間,但總是被回絕,除了前年以外。老爺答應夫人一定會排出空檔,他們在去年的二十三日前往澳洲。」耐耐嘆了口氣。「那一天的晚上,我打電話給媽媽時,她很高興地告