1285

【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

你可能感興趣的文章

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

【MySQL Workbench】如何透過TCP/IP進行SSL連線到遠端MySQL資料庫 通常MySQL伺服器都不是只提供某人連線,而是多人都可以連線進來使用,這時就不能繼續使用localhost的那種寫法

【教程】(進階版)如何用Sigil製作一本高質量的epub 下載好了Sigil之後除了直接把文字貼進去以外,還有:變更字型、著色、導入CSS……等等功能,不知道你有沒有發現呢?

【PaperMC】從 Waterfall 切換至 Velocity waterfall 已經停止支援,最後停留在支援 Minecraft 1.21.6,之後的 Minecraft 版本便不再支援

【Wickct】(縮短網址) 如何將網頁掛載到特定路徑下 Wildfly的預設網址又臭又長又不好記,而且會被看到後端的目錄路徑安排,當然能藏就盡量藏起來啦

【C】(%c, %d)解決讀取字元時的緩衝區殘留 不解決就會莫名其妙地冒出一些莫名其妙的東西

隨機好文

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

高捷少女:小穹與果仁巧克力㊤ 阿敏突然輕笑一聲,從櫃臺拿來一個塑膠餐盒,打開給大家看。「這是小穹烤的餅乾,妳們吃吃看就知道她為什麼不想講了。」小穹變得緊張起來。「阿敏,妳怎麼還留著呀?」艾米莉亞、婕兒與耐耐各自拿了一塊,把夾著奶油

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

【歌評】蓮台野夜行 - 魔術師梅莉(魔術師メリー)  對於同一首歌每一個人都有不同的見解,看看別人對於這一首歌的看法,說不定就可以聽出這首歌想要表達的事情!

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

精讚::