Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++ switch case on char arrays

I have several data structures, each having a field of 4 bytes.

Since 4 bytes equal 1 int on my platform, I want to use them in case labels:

switch (* ((int*) &structure->id)) {
   case (* ((int*) "sqrt")): printf("its a sqrt!"); break;
   case (* ((int*) "log2")): printf("its a log2!"); break;
   case (((int) 'A')<<8 + (int) 'B'): printf("works somehow, but unreadable"); break;
   default: printf("unknown id");
}

This results in a compile error, telling me the case expression does not reduce to an int.

How can i use char arrays of limited size, and cast them into numerical types to use in switch/case?

like image 512
i_want_to_learn Avatar asked Aug 16 '11 19:08

i_want_to_learn


People also ask

Can Switch case be used for char in C?

You can use char 's for the switch expression and cases as well.

Can switch condition have a character array?

You can't because the switch variable must be an integer or a variable that can be resolved to an integer. It looks like you will need to use a series of ifs. Match the incoming string against an array of strings and just use the array index.

Do switch statements work with char?

Unlike if-then and if-then-else statements, the switch statement can have a number of possible execution paths. A switch works with the byte , short , char , and int primitive data types.


2 Answers

Follow the exact method employed in video encoding with FourCC codes:

Set a FourCC value in C++

#define FOURCC(a,b,c,d) ( (uint32) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a)) )

Probably a good idea to use enumerated types or macros for each identifier:

enum {
    ID_SQRT = FOURCC( 's', 'q', 'r', 't'),
    ID_LOG2 = FOURCC( 'l', 'o', 'g', '2')
};

int structure_id = FOURCC( structure->id[0], 
                           structure->id[1],
                           structure->id[2],
                           structure->id[3] );
switch (structure_id) {
case ID_SQRT: ...
case ID_LOG2: ...
}
like image 190
Steve-o Avatar answered Sep 21 '22 02:09

Steve-o


Disclaimer: Don't use this except for fun or learning purposes. For serious code, use common idioms, never rely on compiler specific behaviour in the general case; if done anyway, incompatible platforms should trigger a compile time error or use the good, general code.


It seems the standard allows multi-character character constants as per the grammar. Haven't checked yet whether the following is really legal though.

~/$ cat main.cc

#include <iostream>

#ifdef I_AM_CERTAIN_THAT_MY_PLATFORM_SUPPORTS_THIS_CRAP
int main () {
    const char *foo = "fooo";
    switch ((foo[0]<<24) | (foo[1]<<16) | (foo[2]<<8) | (foo[3]<<0)) {
    case 'fooo': std::cout << "fooo!\n";  break;
    default:     std::cout << "bwaah!\n"; break;
    };
}
#else
#error oh oh oh
#endif

~/$ g++ -Wall -Wextra main.cc  &&  ./a.out
main.cc:5:10: warning: multi-character character constant
fooo!

edit: Oh look, directly below the grammar excerpt there is 2.13.2 Character Literals, Bullet 1:

[...] An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharac- ter literal has type int and implementation-defined value.

But in the second bullet:

[...] The value of a wide-character literal containing multiple c-chars is implementation-defined.

So be careful.

like image 31
Sebastian Mach Avatar answered Sep 22 '22 02:09

Sebastian Mach