switch case scanf(”%c”)

2009-09-29 4:24 am
以下是我的程式碼...
不知道為什麼scanf("%c",&b)→這一題毫無作用...求解,感謝。

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

int main(void)
{
int a;
char b;


scanf("%d",&a);

switch (a)
{
case 1:
printf ("000000000 \n");
scanf ("%c",&b);
printf("%c",b);
break;

case 2:
printf ("100000000 \n");
scanf ("%d",&b);
printf("%d",b);
break;

default :
printf ("000000001 \n");
scanf ("%d",&b);
printf("%d",b);
break;
}



system("PAUSE");
return 0;
}

回答 (6)

2009-09-29 8:56 am
✔ 最佳答案
你的程式僅有一個「受制於人(scanf)」的被動問題!
過去曾有不少人跟你一樣陷入這個迷惑中,俺也答了不少次!
解決方法出奇的簡單,簡單到會令你扼腕喟嘆!

請把這一行 scanf ("%c",&b);
改成 scanf (" %c",&b);
簡單的在%前面加一個空白,便可藥到病除。
祝你享用愉快!



2009-09-29 14:58:34 補充:
針對scanf的這個現象,導因於標準輸入流(stdin)殘留資料所致。
以你這程式為例,當你 scanf("%d",&a);輸入一個整數時,「enter」鍵仍留在輸入流內,若你接下來執行 scanf ("%c",&b); 這個殘留的「enter 」便會「直接」當成字元資料存入變數b。由於「enter 」字元僅換行,在螢幕看不到輸出字元,所以你「誤」以為沒 printf。

有人因此埋怨scanf為何不自動先清除輸入流,但真正深入研究後,會讚許scanf的這種安排,因為有蠻多進階的應用上,需要保留輸入流的完整性!這說來話長,無暇贅述。

2009-09-29 15:00:08 補充:
(續上)
這就好像上餐舘,上了一道素菜,要何口味,允許你自行添加酸甜苦辣。
scanf 便提供了一個調味料,讓它在接收格式化資料之前,先清掉殘留的空白字元(包含enter),這個調味料,便是俺在回答內文所述的。(既是調味料,簡單當然是第一要務。)

另外,你在炒菜時,若誤把砂糖當鹽用,壞了一鍋菜,只好丟棄重做。
同理,scanf 時,若誤把字元當數值輸入,便會錯誤,這時便得自行清除輸入流的資料再重新執行 scanf ,簡易的用法之一便是用 fflush(stdin)。

2009-09-29 15:18:11 補充:
(續上)
請善用 fflush(stdin) 在合理的地方,而非一朝被蛇咬,十年怕草繩,逢scanf 便套用一下,這便濫用了!
舉一個簡單的例子,若你設計一個中(英)文輸入練習的程式,便不能濫用 fflush(stdin),否則 keyin 高手也會望天長嘆!
但在處理scanf的錯誤時,fflush(stdin) 卻又不失為一個簡易好用的工具。
2009-09-30 6:27 am
綿羊的這個程式有癌症!!千萬別用!




這篇用 fflush(stdin) 是個安全牌;
不過,安全牌 不等於 上策!
永遠只用安全牌,成不了氣候!



略看過 Circle 不少回答,基本上不差;
不過,這篇的解說確實有誤!
不信?研究一下丫旺的意見!就會發現我說的是對的!
2009-09-30 4:19 am
其實不是Enter鍵殘留在Buffer(stdin)中!

而是按下Enter鍵時需告訴Console要執行換行!

畢竟電腦是一個指令一個動作滴不告訴她要換行怎會換呢?

按下Enter鍵的同時也增加了LF的ASCII碼到Buffer中當作換行用!

LF=Line Feed也就是'\n'的意思

LF的ASCII碼為0A H(10)

而Enter鍵的ASCII碼為0D H(13)

所以當你要讀取一個字元時很容易就會出現錯誤

依據你的程式輸入1時印出000000000後scanf ("%c",&b)就會讀入

\n放入b變數中所以你執行printf("%c",b)時會直接跳下一行!

要解決這問一有很多方法如stdin內的內容均不重要

用fflush(stdin)即可!

2009-09-29 20:45:02 補充:
如果有重要的資料可以改scanf(" %c",&b)在%c前加上一個空白那讀取字元時'\n'就會被跳過!

也可以在scanf(" %c",&b)前多加一行

if((b=getc(stdin))!=10)ungetc(b,stdin);

如果b得到的不是換行字元('\n')則將getc()得到的字元(b)回放至stdin(標準輸入檔中)
2009-09-30 1:54 am
轉個彎看世界.若你只想取"一個文字"使用以下方式會比較方便
#include < stdio.h>
#include < stdlib.h>
#include < conio.h>

int main()
{
char b;

b=getch(); // 第一種.不必輸入[Enter]
b=getchar(); // 第二種.需要輸入[Enter]
printf ("%c",b);
return system("PAUSE");
}
2009-09-29 8:54 pm
因為你在輸入a值之後按下的enter鍵會被當做是一筆輸入
而被放入輸入的緩衝區中
因此在遇到下一次要求使用者輸入資料時
會先檢查緩衝區內是否有適用的資料
此時你的b要求是為一字元 enter鍵就被當成輸入存入變數b
若怕使用者亂輸入而影響到你的程式的話
可以使用fflush(stdin);
這個指令是將輸入緩衝區內的所有資料清除
因此可以將此指令加在每一個scanf( )之前
例如
fflush(stdin);
scanf ("%c",&b);
如此一來可以確保每次要求使用者輸入資料時
不會有之前輸入資料時遺留下來的其他資料

另外
有時候有在迴圈內要求使用者輸入整數資料時
若不小心輸入非整數資料時會造成程式進入無止盡的迴圈
(因為在緩衝區內找不到整數資料而造成程式當掉)
在scanf( )之前加上fflush(stdin);也可以解決這類的問題
不過缺點是程式碼會比較長一些

希望對你有幫助
參考: 自己
2009-09-29 6:18 am
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a;
//宣告成字串(字元陣列)
char b[2];
scanf("%d",&a);
switch (a)
{
case 1:
printf ("000000000 \n");
//
//在此建議改寫成字串的輸入輸出
//
scanf ("%s",b);
printf("%s",b);
break;
case 2:
printf ("100000000 \n");
scanf ("%s",b);
printf("%s",b);
break;
default :
printf ("000000001 \n");
scanf ("%s",b);
printf("%s",b);
break;
}
system("PAUSE");
return 0;
}
參考: 字串有結束字元,令電腦等待使用者輸入!


收錄日期: 2021-04-30 14:01:42
原文連結 [永久失效]:
https://hk.answers.yahoo.com/question/index?qid=20090928000016KK06980

檢視 Wayback Machine 備份