问题
I have the following code
#define SWITCH(S) char *_S = S; if (0)
#define CASE(S) } else if (strcmp(_S, S) == 0) {switch(1) { case 1
#define BREAK }
#define DEFAULT } else {switch(1) { case 1
int main()
{
char buf[256];
printf("\nString - Enter your string: ");
scanf ("%s", buf);
SWITCH (buf) {
CASE ("abcdef"):
printf ("B1!\n");
BREAK;
CASE ("ghijkl"):
printf ("C1!\n");
BREAK;
DEFAULT:
printf ("D1!\n");
BREAK;
}
}
If I generate the pre-processor code with gcc -E
, I will get the following code
int main()
{
char buf[256];
printf("\nString - Enter your string: ");
scanf ("%s", buf);
char *_S = buf;
if (0) {
} else if (strcmp(_S, "abcdef") == 0) {switch(1) { case 1:
printf ("B1!\n");
};
} else if (strcmp(_S, "ghijkl") == 0) {switch(1) { case 1:
printf ("C1!\n");
};
} else {switch(1) { case 1:
printf ("D1!\n");
};
}
}
But for some gcc defining char *_S = buf;
in the middle of the code is not wolcome and could provide compilation error
How to fix that in my macro?
Please do not suggest to define char *_S
as global (out of the main
)
回答1:
Remove the macros altogether, and write it in the "expanded" way, moving the declaration to the top. These macros are horrific.
Failing that, tweak SWITCH
to introduce a new scope (a second {
). This will of course force you to have to close two scopes, so perhaps add a SWITCH_END
abomination to use at the end, to encapsulate that. Whatever.
回答2:
Oh no!!!
I wrote this as a joke in this post
Don't use it is very very horrific, if you want to avoid if-else you can do it without torturing the compiler, consider using pair of strings:
#include <stdio.h>
#include <string.h>
int main(void)
{
char buf[256];
const char *ap[] = {
"abcdef", "B1!\n",
"ghijkl", "C1!\n",
NULL , "D1!\n",
}, **p = ap;
printf("\nString - Enter your string: ");
scanf ("%s", buf);
while (*p) {
if (strcmp(buf, *p) == 0) break;
p += 2;
}
printf("%s", *(++p));
return 0;
}
回答3:
Make sure the code is being compiled as C99 or later; otherwise, you will need to use a different control structure.
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
SWITCH(buf)
{
...
}
#else
if (strcmp(buf, "abcdef") == 0)
{
...
}
else if (strcmp (buf, "ghijkl") == 0)
{
...
}
else
{
...
}
#endif
It's generally not a good idea to use the preprocessor to "alter" or extend C syntax (I have the scar tissue to prove it); switch
isn't defined on string expressions for a reason.
If you really want to use a switch
in this situation, then it may be better to code up a hash function that returns a key for each string, and switch on the result:
#define ABCDEF ... // hash key generated for "abcdef"
#define GHIJKL ... // hash key generated for "ghijkl"
...
switch(hash(buf))
{
case ABCDEF :
...
break;
case GHIJKL :
...
break;
default:
...
break;
}
来源:https://stackoverflow.com/questions/14219156/how-to-switch-and-case-for-string