从if语句到switch语句?

时间:2018-04-12 03:07:29

标签: c if-statement 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时,它立即默认为“错误选择”而不是调用我的翻译功能(或退出程序)

4 个答案:

答案 0 :(得分:2)

我认为您应该使用int choice而不是char choice,然后将scanf%s更改为%d

答案 1 :(得分:0)

您使用了字符串标记%s而不是%c,最好使用int而不是char。希望它有所帮助!

答案 2 :(得分:0)

将选择的数据类型设置为int 并更改scanf("%d",& choice); 像这样

答案 3 :(得分:0)

虽然您可以使用scanf来获取用户输入,但您不应该这样做。等待捕获与其使用相关的新C程序员有很多陷阱。要正确使用它,您必须始终验证其返回并处理以下情况:

  1. 您收到有效输入(返回值是请求的转化次数);
  2. 发生匹配输入失败(返回小于请求的数量,不再读取其他字符,在输入缓冲区中保留所有无效输入,例如{{1 }});和
  3. 用户使用手动stdin取消输入(返回为EOF);和
  4. 您必须始终考虑先前I / O呼叫留在输入缓冲区中的任何字符。
  5. 每次输入都必须这样做。不同的转换说明符如何处理前导空格(数字和EOF忽略前导空格,字符和字符类(例如%s)不这样做,这进一步复杂化。

    这就是采用用户输入的首选方法是%[..](或POSIX fgets)。两者都是面向行的输入函数,它们读取(包括)尾随getline(由用户按Enter键生成)。您仍然必须验证两者的返回并根据需要处理尾随'\n',但由于未能解释未读的字符而陷入陷阱的可能性会显着降低。

    考虑到上述情况,并为'\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 (buffer, size, FILE* stream)。然后,继续检查长度,确保输入符合NULL个字符,最后一个字符为size(否则字符仍未读取)。如果您正在存储字符串,或者不记录最后一个字符为'\n',则可以通过用'\n'覆盖它来删除它(与0相同 - 无字符)

    阅读选择很简单:

    '\0'

    现在您已在 /* 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语句中的每个case进行比较即可。这就像将解除引用的switch传递给choice一样简单(即switch只是指向第一个字符的指针,因此dereferncing返回第一个字符本身,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

    通过按 Ctrl + d (Windows with legacy mode enabled on Win10上的 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: 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 ,无效输入和用户取消:

    EOF

    仔细看看,如果您有其他问题,请告诉我。