如何为字符串切换和大小写?

时间:2013-01-08 16:07:13

标签: c macros

我有以下代码

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

如果我使用gcc -E生成预处理器代码,我将获得以下代码

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

但是对于某些在代码中间定义char *_S = buf;的gcc而言,并不会产生编译错误

如何在我的宏中修复它?

请不要建议将char *_S定义为全局(main之外)

3 个答案:

答案 0 :(得分:8)

完全删除宏,并以“扩展”方式写入,将声明移到顶部。这些宏很可怕。

如果失败,请调整SWITCH以引入新范围(第二个{)。这当然会迫使你必须关闭两个范围,所以也许最后要添加一个SWITCH_END憎恶来封装它。不管。

答案 1 :(得分:8)

哦不!!!!

我在this post

中写了这个笑话

不要使用它是非常可怕的,如果你想避免if-else你可以在不折磨编译器的情况下做到这一点,考虑使用字符串对:

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

答案 2 :(得分:1)

确保代码编译为C99或更高版本;否则,您将需要使用不同的控制结构。

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L

  SWITCH(buf)
  {
    ...
  }

#else

  if (strcmp(buf, "abcdef") == 0)
  {
    ...
  }
  else if (strcmp (buf, "ghijkl") == 0)
  {
    ...
  }
  else
  {
    ...
  }

#endif

使用预处理器“改变”或扩展C语法通常不是一个好主意(我有疤痕组织来证明它);由于某种原因,未在字符串表达式上定义switch

如果确实想在这种情况下使用switch,那么编写一个为每个字符串返回一个键的哈希函数可能会更好,并打开结果:

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