darksky
darksky

Reputation: 21019

Switch Statement in C

I have the following if-statements:

    if (strcmp(registerName, "zero"))
            return 00000;
    else if (strcmp(registerName, "at"))
        return 00001;
    else if (strcmp(registerName, "v0"))
        return 00010;
    else if (strcmp(registerName, "v1"))
        return 00011;

It's actually really long - about 20 if-statements. Therefore, I would like to use a switch. How would I convert that to switch when each statement has a different condition?

I tried something as the code below, but it does not work:

int registerAddress;

switch(registerAddress) {

case 1 (strcmp(registerName, "zero")):
        regsiterAddress = 00000;
        break;
case 2 (strcmp(registerName, "at")):
        registerAddress = 00001;
        break;
}

Upvotes: 6

Views: 3872

Answers (5)

Udo Klein
Udo Klein

Reputation: 6882

Why not use the ? operator like so:

return
    strcmp(registerName, "zero")? 00000:
    strcmp(registerName, "at")  ? 00001:
    strcmp(registerName, "v0")  ? 00010:
    strcmp(registerName, "v1")  ? 00011:
    ...

Upvotes: 1

nos
nos

Reputation: 229058

You can only switch on integers, so this will not work.

If all you're doing is converting a string to an int, store the info in an array and look through it.

struct {
   const char *name;
   int value;
} fooMapping[] = {
     {"zero",0},
     {"at",1}
      ....
};

int foo2value(const char *name)
{
     size_t i;
     for(i = 0; i < sizeof fooMapping/sizeof fooMapping[0]; i++) {
          if(strcmp(name, fooMapping[i].name) == 0) 
             return fooMapping[i].value;

     }
    return -1;
}

Upvotes: 7

Raymond Hettinger
Raymond Hettinger

Reputation: 226171

Since switch-case only works with numbers or single chars, I would use a tool like GNU's gperf to create a perfect hash and switch on that value (followed by a strcmp() to be certain of an exact match). That ought to give you the desired performance improvement.

Upvotes: 0

Gabriel
Gabriel

Reputation: 3045

In a switch,

switch(number) {

case 1;
case 2;
case 7;
}

you are basically saying, if number = 1, then case 1. If number = 7, case 7. So what you need to do is assign each text value, in your case "zero""at""v0" and "v1", you would need to put these into an array, and in the switch statement, instead of switch(number) you would switch an integer that would correspond with the index number of whichever text you had. So if array[3] was = "v0", you would assign an integer to the index number (3) and then switch(integer). Hope this helped.

Upvotes: 1

Ilmari Karonen
Ilmari Karonen

Reputation: 50328

You can't — switch statements in C only work on primitive types, not on strings. You could use, say, a hash table or a search tree to optimize the matching, but for only 20 options that may not be worth the trouble.

What you could do, to clean up the code, is set up a mapping table:

struct str2Num {
    char *str;
    int num;
};

const struct str2Num registerMap[] = {
    { "zero", 00000 },
    { "at", 00001 },
    { "v0", 00010 },
    { "v1", 00011 },
    { NULL, 0 }  /* end marker */
};

and do your matching like this:

int i;
for (i = 0; registerMap[i].str != NULL; i++) {
    if (strcmp(registerName, registerMap[i].str) == 0) {
        return registerMap[i].num;
    }
}
/* handle no-match case here */

In fact, if you sorted the table alphabetically, you could even use bsearch() for fast matching.

Upvotes: 7

Related Questions