[問題] switch...case的問題

看板C_and_CPP作者 (Dain)時間7年前 (2017/09/08 02:23), 編輯推噓9(9042)
留言51則, 12人參與, 最新討論串1/1
開發平台(Platform): (Ex: Win10, Linux, ...) Win7 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) Dev C++ 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) stdio.h stdlib.h 問題(Question): 為什麼我的switch...case,無法成功載入,會直接跳default:("Error\n); 餵入的資料(Input): 預期的正確結果(Expected Output): printf("Choice your mode: A.Read B.Write C.Randread D.Randwrite E.Randr F.RWmixread=70 \n"); scanf("%c", &mode); 輸入A.B.C.D.E等,會printf出來結果 錯誤結果(Wrong Output): 結果直接跳到Error 程式碼(Code):(請善用置底文網頁, 記得排版) #include<stdio.h> #include<stdlib.h> int main() { char filename[10]; int iodepth, bs, size, numjobs, runtime; printf("Where is your file? (absult postion)\n"); scanf("%s", filename); printf("Setting your IO module(default=1)\n"); scanf("%d", &iodepth); printf("What is your I/O size(-bs)?\n"); scanf("%d", &bs); printf("How much the test file size\n"); scanf("%d", &size); printf("How many your number of jobs?\n"); scanf("%d", &numjobs); printf("How long do you wany to test?(sec)\n"); scanf("%d", &runtime); char mode; printf("Choice your mode: A.Read B.Write C.Randread D.Randwrite E.Randrw F.RWmixread=70 \n"); scanf("%c", &mode); switch(mode) { case 'A': printf("Fuck u\n"); printf("fio -filename=%s -direct=1 -iodepth %d -thread -rw=read ioengine=libaio -bs=%dm -size=%dG -numjobs=%d -runtime=%d -group_reporting -name=mytest\n", filename, iodepth, bs, size, numjobs, runtime); break; case 'B': printf("fio -filename=%s -direct=1 -iodepth %d -thread -rw=write ioengine=libaio -bs=%dm -size=%dG -numjobs=%d -runtime=%d -group_reporting -name=mytest\n", filename, iodepth, bs, size, numjobs, runtime); break; case 'C': printf("fio -filename=%s -direct=1 -iodepth %d -thread -rw=randread ioengine=libaio -bs=%dm -size=%dG -numjobs=%d -runtime=%d -group_reporting -name=mytest\n", filename, iodepth, bs, size, numjobs, runtime); break; case 'D': printf("fio -filename=%s -direct=1 -iodepth %d -thread -rw=randwrite ioengine=libaio -bs=%dm -size=%dG -numjobs=%d -runtime=%d -group_reporting -name=mytest\n", filename, iodepth, bs, size, numjobs, runtime); break; case 'E': printf("fio -filename=%s -direct=1 -iodepth %d -thread -rw=randrw ioengine=libaio -bs=%dm -size=%dG -numjobs=%d -runtime=%d -group_reporting -name=mytest\n", filename, iodepth, bs, size, numjobs, runtime); break; default: printf("Error\n"); } return 0; } 補充說明(Supplement): -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.251.10.52 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1504837410.A.4BB.html

09/08 10:32, , 1F
你先把 mode 印出來看看啊
09/08 10:32, 1F

09/08 10:52, , 2F
可能因為code有髒話被和諧了
09/08 10:52, 2F

09/08 11:02, , 3F
嗚嗚嗚 那句話是因為翻爛了一堆C語言的書,還是沒結果
09/08 11:02, 3F

09/08 11:04, , 4F
我用printf看了下,mode沒答案
09/08 11:04, 4F

09/08 11:05, , 5F
大小寫?
09/08 11:05, 5F

09/08 11:10, , 6F
mode沒答案? 那八成是吃到換行了
09/08 11:10, 6F

09/08 11:16, , 7F
應該是runtime的換行被mode吃進去了吧
09/08 11:16, 7F

09/08 11:17, , 8F
吃進去? 那請問要怎麼解決這問題??
09/08 11:17, 8F

09/08 11:19, , 9F
先把換行吃掉再scanf就好
09/08 11:19, 9F

09/08 11:20, , 10F
getc(stdin)
09/08 11:20, 10F

09/08 11:20, , 11F
scanf(" %c", &mode); 試試看
09/08 11:20, 11F

09/08 11:24, , 12F
s大,我資質餘噸,剛入寫程式,所以還是有點不太了解
09/08 11:24, 12F

09/08 11:24, , 13F
可以給我關鍵字之類的,我很願意自己google學習
09/08 11:24, 13F

09/08 11:25, , 14F
enonrick 我還沒用過那個指令過,我會上網查的
09/08 11:25, 14F

09/08 11:26, , 15F
shadow0326 我剛試過,他還是顯示Error
09/08 11:26, 15F

09/08 11:28, , 16F
scanf newline ←用這個google?
09/08 11:28, 16F

09/08 11:32, , 17F
一時之間想不到用什麼關鍵字可以找到相關問題……
09/08 11:32, 17F

09/08 11:32, , 18F
也許可以試試scanf input buffer之類的
09/08 11:32, 18F

09/08 11:33, , 19F
簡單來說就是上次輸入的時候,例如輸入123然後[Enter]
09/08 11:33, 19F

09/08 11:34, , 20F
輸入緩衝區會填入"123\n"。上個scanf只consume掉整數的
09/08 11:34, 20F

09/08 11:36, , 21F
"123"部分,下一個scanf("%c", ...)讀到的就是還留在
09/08 11:36, 21F

09/08 11:36, , 22F
buffer裡面的"\n"。
09/08 11:36, 22F

09/08 11:37, , 23F
吃到換行了 scanf前面放一個getchar把它吃掉就好
09/08 11:37, 23F

09/08 11:39, , 24F
所以只要想辦法把那個"\n"吃掉就好,樓上說的getchar()
09/08 11:39, 24F

09/08 11:39, , 25F
就是其中一個方法。
09/08 11:39, 25F

09/08 11:41, , 26F
或是這樣 scanf("%d\n", &runtime);
09/08 11:41, 26F

09/08 11:42, , 27F
https://ideone.com/1c9N0a 為什麼我可以QQ
09/08 11:42, 27F

09/08 11:42, , 28F
還有是Choose your mode不是Choice... (離題)
09/08 11:42, 28F

09/08 11:44, , 29F
那我想再問一下,到底怎麼看出來的啊?因為我都看書
09/08 11:44, 29F

09/08 11:45, , 30F
書上沒解釋到這個過
09/08 11:45, 30F

09/08 11:50, , 31F
shadow0326 那我再試試看,可能我有地方少打
09/08 11:50, 31F

09/08 11:55, , 32F
摁...... IDE可以設中斷點觀察變數的值 可以發現mode吃到
09/08 11:55, 32F

09/08 11:56, , 33F
'\n' 之後應該會發現是scanf的問題 去google scanf 換行
09/08 11:56, 33F

09/08 11:57, , 34F
就可以找到一些想看的東西
09/08 11:57, 34F

09/08 12:13, , 35F
有些入門書會省略細節,沒有解釋。C Primer Plus中好像
09/08 12:13, 35F

09/08 12:14, , 36F
有提到這方面的東西。不過其實主要還是像樓上說的,
09/08 12:14, 36F

09/08 12:14, , 37F
用debugger觀察然後再google問題。
09/08 12:14, 37F

09/08 13:20, , 38F
感謝各位大大的幫忙,我已經成功可以輸出進到switch了
09/08 13:20, 38F

09/08 14:28, , 39F
scanf前先用fflush(stdin)應該也可以解決這問題
09/08 14:28, 39F

09/08 17:08, , 40F
fflush(stdin)記得不是標準做法
09/08 17:08, 40F

09/08 17:10, , 41F

09/08 17:15, , 42F
謝謝J大,受教了
09/08 17:15, 42F

09/08 17:30, , 43F
有人知道最早做fflush(stdin)的是哪個編譯器嗎XD
09/08 17:30, 43F

09/08 17:30, , 44F
其實我覺得所有編譯器都做成清除stdin也不錯?
09/08 17:30, 44F

09/08 20:18, , 45F
不這樣做是因為以前有些硬體的限制沒辦法 flush stdin 吧
09/08 20:18, 45F

09/08 20:18, , 46F
09/08 20:18, 46F

09/08 21:47, , 47F
我自己的習慣上,只用printf大法時
09/08 21:47, 47F

09/08 21:47, , 48F
會在目標變數周圍加上[],以防有甚麼肉眼看漏的東西
09/08 21:47, 48F

09/08 21:47, , 49F
被我忽略
09/08 21:47, 49F

09/11 13:47, , 50F
也有個可能是某些平台的 implementation 就有這個副作用
09/11 13:47, 50F

09/11 13:47, , 51F
然後被開發人員 exploit 之後就只好一直維護了
09/11 13:47, 51F
文章代碼(AID): #1PiVyYIx (C_and_CPP)