簡體   English   中英

從if語句到switch語句?

[英]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程序員。 為了正確使用它,您必須始終驗證它的退貨並處理以下情況:

  1. 您收到有效的輸入(返回是請求的轉換數);
  2. 匹配輸入失敗(返回小於請求的數量,不再讀取任何字符,將所有無效輸入保留在輸入緩沖區中,例如stdin );
  3. 用戶使用手動EOF取消輸入(返回為EOF );
  4. 您必須始終考慮上一個I / O調用留在輸入緩沖區中的所有字符。

您必須對每個輸入都執行此操作。 不同的轉換說明符如何處理前導空格(數字和%s忽略前導空格,字符和字符類(例如, %[..]則不這樣做))使情況更加復雜%[..]

這就是為什么采用用戶輸入的首選方法是使用fgets (或POSIX getline )。 兩者都是面向行的輸入函數,最多可讀取(包括)尾隨的'\\n' (由用戶按Enter生成)。 您仍然必須驗證兩者的返回值,並根據需要處理尾隨的'\\n' ,但是由於未能考慮未讀字符而導致陷入陷阱的可能性已大大降低。

考慮到上述因素,並為choicestr使用固定緩沖區(傳遞給函數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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM