【问题标题】:How to properly use C switch statement如何正确使用C switch 语句
【发布时间】:2020-09-01 13:55:11
【问题描述】:

我有一个代码 sn-p,我用它来学习一些 C

char* input( char *s ){
    scanf("%[^\n]%*c",s);
    return s;
}
void main()
{
    printf("Welcome to a string input/output example written in C! \n");
    printf("Type e to exit \n");
    printf(" \n");  
    while (0 == 0){ 
        printf("> ");
        char str[100];
        input( str );
        //All off this code works perfectly until the switch statement, which apparently cannot recognized the 'e' case:
        switch(str){
            case 'e'    :   break;
            default     :   printf("Your string is: %s \n", str);           
        }

    }
}

然而,当这段代码运行时,它返回的字符串很好,但是在 switch 语句期间它默认为默认值,即使“str”的值为“e”,它也会返回:

你的字符串是:e

而不是退出。请帮忙,这很奇怪..

【问题讨论】:

  • while (0 == 0) 是无意义的代码。只需使用while (1)for (;;)
  • 提示:你不能在 C 字符串上使用switch。使用strcmp
  • switch 在 C 中仅用于整数分支。
  • 另外,switch 内的break 不会脱离while 循环。

标签: c string switch-statement c-strings


【解决方案1】:

switch 中的 break 语句退出 switch 语句。如果开关在循环内,它不会退出循环。只是 switch 语句。

【讨论】:

    【解决方案2】:

    您不能在 C 中将开关与字符串一起使用。您现在正在做的是使用指向开关中数组 str 中第一个字符的指针。这就是为什么总是转到默认部分。 做你想做的事的一个好方法是使用 strcmp: int strcmp(const char *str1, const char *str2); 如果返回值

    如果返回值>0,则表示str2小于str1。

    如果返回值=0,则表示str1等于str2。

    char str2[]="e";
    if(strcmp(str, str2))
        printf("Your string is: %s \n", str);
    else
        break;
    

    同样不要使用 while(0==0),改用 while(1)

    【讨论】:

      【解决方案3】:

      你不能切换字符串。您可以改用if ... else if

      while (1){ 
              printf("> ");
              char str[100];
              input( str );
              if(strcmp(str, "e") == 0){ // type e to exit
                      break;
      
              } else if (strcmp(str, "abc") == 0) { // if you type abc
                  // do something
      
              } else if (strcmp(str, "def") == 0) { // if you type def
                  // do something
      
              } else { // it's a mimic of default in switch statement.
                  printf("Your string is: %s \n", str);
              }
      
          }
      

      使用strcmp 比较字符串。在您的代码中,'e' 是字符,而不是字符串。你必须使用" 而不是'

      在此处查看更多信息Best way to switch on a string in C

      如果您仍然想要switch,请阅读How to switch and case for string?

      【讨论】:

        【解决方案4】:

        很遗憾,您的编译器没有警告您尝试打开字符串指针而不是字符串数组的第一个 字符。我的说:

        “错误C2050:开关表达式不是整数”

        你仍然可以做一些事情:

        switch(str[0])
        

        (如果您在终止的 null 上添加额外的检查,它是一个 1 字符的字符串)

        老实说,我不认识您的 scanf() 语法,但我从不使用 scanf() ,因为如果您不小心,它可能会意外地超出您的缓冲区。相反,我会使用 getchar() 一次读取一个字符,但有最大限制。

        最后,你的 switch break 只会跳出内部 switch 语句。您需要第二次休息才能跳出封闭循环。

        确保我没有犯错或进一步修改:

        #include <stdio.h>
        #include <ctype.h>
        
        
        char* input( char *s, size_t max ){
            size_t i = 0;
            int c;
            int skipped_space = 0;
        
            for(;;) {
                c = getchar();
                if(EOF == c) {
                    // error
                    break;
                }
        
                if(!skipped_space) {
                    if(!isspace(c)) {
                        skipped_space = 1;
                        if(i < max) {
                            s[i++] = c;
                        }
                    }
                } else {
                    if(isspace(c)) {
                        break;
                    }
        
                    if(i < max) {
                        s[i++] = c;
                    }
                }
            }
        
            if(EOF != c  &&  i < max) {
                // success
                s[i] = '\0';
            } else {
                // failure or buffer overrun
                s = NULL;
            }
        
            return s;
        }
        
        void main()
        {
            int done = 0;
        
            printf("Welcome to a string input/output example written in C! \n");
            printf("Type e to exit \n");
            printf(" \n");
            for(;;) {
                printf("> ");
                char str[100];
                if(input( str, 100 )) {
                    switch(str[0]){
                        case 'e'    :
                            if('\0' == str[1]) {
                                done = 1;
                                break;
                            }
        
                        default:
                            printf("Your string is: \"%s\" \n", str);
                            break;
                    }
        
                    if(done)
                        break;
                } else {
                    printf("Error.\n", str);
                }
            }
        }
        

        【讨论】:

        • 这是更多的代码,但为什么是 getchar > scanf?
        【解决方案5】:

        如果您使用辅助函数,则可以在 C 中将 switch 与字符串一起使用。在某些情况下,这可能是处理字符串输入的更优雅的方法。

        这个帮助函数接受一个空终止模式的字符串,其中最后一个模式是双空终止(显式使用 \0 并且由于字符串的结尾而隐式使用):

        int strswitch (const char * str, const char * patterns)
        {
            int index = 0;
            size_t len;
            while (patterns && (len = strlen(patterns)) != 0) {
                if (strcmp(str, patterns) == 0)
                    return index;
                index++;
                patterns += len + 1;    // next pattern
            }
            return -1;
        }
        

        然后要将 switch 语句与助手一起使用,请执行以下操作:

        switch (strswitch(str,
            "e\0"
            "abc\0"
            "def\0"
            ))
        {
            case 0 :    // "e"
                // handle "e" case
                break;
            case 1 : // "abc"
                // do something
                break;
            case 2 : // "def"
                // do something
                break;
            default :
                printf("Your string is: %s \n", str);
                break;
        }
        

        辅助函数不需要被限制为精确匹配。根据您的需要,您可以编写一个只进行部分匹配或使用正则表达式等的。

        【讨论】:

          猜你喜欢
          • 2021-06-04
          • 2021-06-12
          • 1970-01-01
          • 1970-01-01
          • 2021-02-28
          • 1970-01-01
          • 2015-01-10
          相关资源
          最近更新 更多