[英]From an if statement to a switch statement?
對於入門課程,我必須編寫一個從英語到豬拉丁語,反之亦然的程序,而且我不明白為什么在驗證不接受字母輸入后為什么不能繼續我的switch語句。 這是我的代碼的一部分:
int main()
{
char choice;
while (1) {
printf("Press 1 to translate from English to pig Latin.\nPress 2 to translate from pig Latin to English.\nPress 3 to terminate the program.\nEnter your choice.\n");
scanf("%s",&choice);
if (isalpha (choice)) {
printf ("ERROR: Please enter a valid input\n");
continue;
}
switch (choice) {
case 1:
printf("Enter the English sentence.\n");
scanf("%s",str);
englishToPig();
break;
case 2:
printf("Enter the pig Latin sentence.\n");
scanf("%s",str);
pigToEnglish();
break;
case 3:
return 0;
default:
printf("Wrong Choice\n");
break;
}
}
return 0;
}
編輯:開關在技術上確實可以正常工作,但是每當我輸入1、2或3時,它立即默認為“錯誤選擇”,而不是調用我的翻譯函數(或退出程序)
我認為您應該使用int choice
而不是char choice
,然后將您的scanf
從%s
更改為%d
您已經使用了字符串標記%s
來代替%c
,更好地使用了int
代替char
。 希望能幫助到你 !
將選擇的數據類型設置為int並更改scanf(“%d”,&choice); 像這樣
雖然可以使用scanf
進行用戶輸入,但您不應該這樣做。 有很多陷阱正等待誘使與其使用相關的新C程序員。 為了正確使用它,您必須始終驗證它的退貨並處理以下情況:
stdin
); 和 EOF
取消輸入(返回為EOF
); 和 您必須對每個輸入都執行此操作。 不同的轉換說明符如何處理前導空格(數字和%s
忽略前導空格,字符和字符類(例如, %[..]
則不這樣做))使情況更加復雜%[..]
這就是為什么采用用戶輸入的首選方法是使用fgets
(或POSIX getline
)。 兩者都是面向行的輸入函數,最多可讀取(包括)尾隨的'\\n'
(由用戶按Enter生成)。 您仍然必須驗證兩者的返回值,並根據需要處理尾隨的'\\n'
,但是由於未能考慮未讀字符而導致陷入陷阱的可能性已大大降低。
考慮到上述因素,並為choice
和str
使用固定緩沖區(傳遞給函數englishToPig
等),您可以執行以下簡單操作。
首先,任何時候你需要一個不斷在你的代碼#define
一個(或多個)。 不要在代碼中使用幻數 。 同樣,不要使文本行從頁面的一側散開,預處理器將合並所有字符串文字,並用空格隔開。 這樣可以對菜單提示的輸出進行大量整理:
#define MAXC 256 /* if you need a constant, define one */
int main (void) {
char choice[MAXC] = "", /* initialize choice and str all zero */
str[BUFSIZ] = ""; /* BUFSIZ is 8092 Linux (512 windows) */
size_t len = 0; /* variable for string length tests */
while (1) {
printf ("\nPress 1 to translate from English to pig Latin.\n"
"Press 2 to translate from pig Latin to English.\n"
"Press 3 to terminate the program.\n\n"
"Enter your choice: ");
...
使用fgets
讀取fgets
很簡單fgets (buffer, size, FILE* stream)
。 為了驗證您在緩沖區中的輸入是否正確,只需檢查返回的值是否為NULL
。 這樣就可以進行檢查長度並確保在輸入合適size
的字符和最后一個字符是'\\n'
(否則字符保持未讀)。 如果您要存儲字符串,否則不考慮最后一個字符為'\\n'
,則可以通過將其覆蓋為0
(與'\\0'
相同-nul字符)來刪除它
閱讀選擇很簡單:
/* read choice (up to 255-chars + nul-terminating char */
if (fgets (choice, MAXC, stdin) == NULL) {
fprintf (stderr, "(user canceled input)\n");
break;
}
len = strlen (choice); /* test all chars fit in choice */
if (len == MAXC - 1 && choice[len - 1] != '\n') {
fprintf (stderr, "warning: characters remain unread.\n");
while (fgets (str, BUFSIZ, stdin)) {} /* read/discard chars */
}
現在您可以choice
用戶輸入了,您只需在switch
語句中將每種case
的第一個字符進行比較即可。 這就像傳遞取消引用的choice
以進行switch
一樣容易(即, choice
只是指向第一個字符的指針,因此取消引用將返回第一個字符本身, *choice
等於choice[0]
)
switch (*choice) { /* *choice is the same as choice[0] */
case '1':
printf ("Enter the English sentence.\n");
/* read input in BUFSIZ chunks, passing str to englishToPig */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling englishToPig (str)");
// englishToPig (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '2':
printf ("Enter the pig Latin sentence.\n");
/* read input in BUFSIZ chunks, passing str to pigtoEnglish */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling pigtoEnglish (str)");
// pigtoEnglish (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '3':
return 0;
default:
fprintf (stderr, "error: invalid choice.\n");
break;
}
( 注意:上面,即使用戶輸入的大小超過BUFSIZ
,整個輸入也會以BUFSIZ
塊的形式傳遞給您的函數)。
將上面的內容變成一個簡短的示例,只需添加標題和return
,例如
#include <stdio.h>
#include <string.h>
#define MAXC 256 /* if you need a constant, define one */
int main (void) {
char choice[MAXC] = "", /* initialize choice and str all zero */
str[BUFSIZ] = ""; /* BUFSIZ is 8092 Linux (512 windows) */
size_t len = 0; /* variable for string length tests */
while (1) {
printf ("\nPress 1 to translate from English to pig Latin.\n"
"Press 2 to translate from pig Latin to English.\n"
"Press 3 to terminate the program.\n\n"
"Enter your choice: ");
/* read choice (up to 255-chars + nul-terminating char */
if (fgets (choice, MAXC, stdin) == NULL) {
fprintf (stderr, "(user canceled input)\n");
break;
}
len = strlen (choice); /* test all chars fit in choice */
if (len == MAXC - 1 && choice[len - 1] != '\n') {
fprintf (stderr, "warning: characters remain unread.\n");
while (fgets (str, BUFSIZ, stdin)) {} /* read/discard chars */
}
switch (*choice) { /* *choice is the same as choice[0] */
case '1':
printf ("Enter the English sentence.\n");
/* read input in BUFSIZ chunks, passing str to englishToPig */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling englishToPig (str)");
// englishToPig (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '2':
printf ("Enter the pig Latin sentence.\n");
/* read input in BUFSIZ chunks, passing str to pigtoEnglish */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling pigtoEnglish (str)");
// pigtoEnglish (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '3':
return 0;
default:
fprintf (stderr, "error: invalid choice.\n");
break;
}
}
return 0;
}
上面的代碼處理所有正確或無效輸入的情況,並處理用戶在每個階段生成手動EOF
情況(它會在choice
時退出,如果在str
再次提示)
使用/輸出示例
使用有效輸入:
$ ./bin/fgetspig
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: 1
Enter the English sentence.
My dog has two fleas and my cat has none :)
calling englishToPig (str)
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: 2
Enter the pig Latin sentence.
yMa atca owna asha wota easlfa, uckyla ogda.
calling pigtoEnglish (str)
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: 3
輸入無效並通過按Ctrl + d生成手動EOF
來取消用戶( 在Win10上啟用了舊模式的 Windows上為 Ctrl + z ):
$ ./bin/fgetspig
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: No!
error: invalid choice.
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: (user canceled input)
仔細檢查一下,如果您還有其他問題,請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.