2013-11-26 2 views
4

(Я знаю, что большинство людей собирается сказать, что это ужасно).C Макросы переключателя/корпуса, несколько случаев

Я написал следующие макросы легко писать Переключатели используя строки вместо если/иначе, если/иначе:

#define str_switch(value)         \ 
do {               \ 
    const char * __strswitchptr__ = (value);     \ 
    if(0)             \ 

#define str_case(test)          \ 
    } if(strcmp(__strswitchptr__, (test)) == 0) {   \ 

#define str_default           \ 
    } else {             \ 

#define str_switchend           \ 
} while(0);             \ 

Что я использую этот путь:

char * sVal = "D"; 

str_switch(sVal) 
{ 
str_case("A") 
    printf("Case A"); 
    break; 
str_case("B") 
    printf("Case B"); 
    break; 
str_case("C") 
    printf("Case C"); 
    break; 
str_default 
    printf("Error"); 
} 
str_switchend 

Но я могу» t выяснить, как я могу изменить его, чтобы я мог использовать несколько случаев:

char * sVal = "D"; 

str_switch(sVal) 
{ 
str_case("A") 
    printf("Case A"); 
    break; 
str_case("B") 
    printf("Case B"); 
    break; 
str_case("C") 
str_case("D") 
str_case("E") 
    printf("Case C"); 
    break; 
str_default 
    printf("Error"); 
} 
str_switchend 

Любая идея? Спасибо :-)

+1

потому, что переключатель делает только целочисленные сравнения –

+1

Насколько я знаю вы не можете сравнивать строки с помощью C-переключателя. – Virus721

+0

@ OliverMatthews Ohh ..., ну вы могли бы сделать функцию, которая выплевывала целые числа. – this

ответ

8

Как насчет этого? Когда один случай имеет значение верно, то это будет продолжаться до конца все, если, пока в break встречаются:

#define str_switch(value)         \ 
do {               \ 
    const char * __strswitchptr__ = (value);     \ 
    int __previous_case_true = 0;        \ 
    if(0)             \ 

#define str_case(test)          \ 
    } if( __previous_case_true        \ 
     || strcmp(__strswitchptr__, (test)) == 0) {   \ 
     __previous_case_true = 1;        \ 

#define str_default           \ 
    } {              \ 

#define str_switchend           \ 
} while(0); 
+0

Спасибо за ответ, это умно. Есть ли предел if-nesting для компиляторов? Долгий список случаев может вызвать проблемы? – Virus721

+1

@ Virus721. Если они не вложены. Они последовательны. –

+0

Следующая задача: написать 'str_goto (string)', который будет переходить на 'str_case (string)'. Тогда у вас будет полная реализация 'switch'! – Shahbaz

0

Вы можете использовать переключатель вместо:

char * sVal = "D"; 

while (*sVal) { 
    switch (*sVal) { 
     case 'A': 
      printf("Case A"); 
     break; 

     case 'B': 
      printf("Case B"); 
     break; 

     case 'C': 
     case 'D': 
     case 'E': 
      printf("Case C"); 
     break; 

     default: 
      printf("Error"); 

    } 
    sVal++; 
} 
Смежные вопросы