简体   繁体   中英

How to properly use C switch statement

I have a code snippet that I am using to learn some 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);           
        }

    }
}

However, when this code is run it returns the string fine, however during the switch statement it default to the default and even if the value of "str" is "e", it returns:

Your string is: e

instead of exiting. Please help this is very strange..

You cant use a switch in C with a String. What you are doing now is using the pointer to the first char in the array str in the switch. Thats why always goes to the default section. A good way to do what you want would be using strcmp: int strcmp(const char *str1, const char *str2); if Return value < 0 then it indicates str1 is less than str2.

if Return value > 0 then it indicates str2 is less than str1.

if Return value = 0 then it indicates str1 is equal to str2.

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

Also don't use while(0==0), use while(1) instead

You can not switch string. You can use if... else if instead.

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);
        }

    }

Use strcmp to compare the string. In your code 'e' is character, not string. you have to use " instead of '

See more info here Best way to switch on a string in C

If you still want a switch , read at How to switch and case for string?

A break statement inside a switch exits the switch statement. If the switch is inside a loop, it doesn't exit the loop. Just the switch statement.

It's too bad your compiler didn't warn you about trying to switch on the string pointer instead of the first character of the string array. Mine says:

"error C2050: switch expression not integral"

You could still do something with:

switch(str[0])

(if you add an additional check on the terminating null that it's a 1-character string)

I honestly don't recognize your scanf() syntax, but I never use scanf() anyway because it could accidentally overrun your buffer if you're not careful. Instead, I would use getchar() to read the characters one-at-a-time with a maximum limit.

Finally, your switch break will only break out of the inner switch statement. You'll need a second break to break out of the enclosing loop.

Make sure I didn't make a mistake or revise further:

#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);
        }
    }
}

You can use switch in C with strings if you use a helper function. In some cases this can be a more elegant method of processing string input.

This helper function takes a string of null terminated patterns where the last pattern is double null terminated (explicitly using a \0 and implicitly because of the end of the string):

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;
}

Then to use the switch statement with the helper, do something like:

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;
}

The helper function doesn't need to be restricted to doing exact matches. Depending on your needs you can write one that only does partial matches or uses regular expressions etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM