如何将其作为switch语句编写?

如何将其作为switch语句编写?,c,if-statement,switch-statement,C,If Statement,Switch Statement,我在尝试将这个if语句集合重写为switch语句时遇到了一些问题 这不是练习或其他什么,我只是非常喜欢switch语句的外观。我很难用if条件下的函数来计算 const char* lookup(const char* path) { //if a path exists, compare path to given extensions //if there is a match, return the appropriate output if (path != NU

我在尝试将这个if语句集合重写为switch语句时遇到了一些问题

这不是练习或其他什么,我只是非常喜欢switch语句的外观。我很难用if条件下的函数来计算

const char* lookup(const char* path)
{
    //if a path exists, compare path to given extensions
    //if there is a match, return the appropriate output
    if (path != NULL) {
        //using strcasecmp is useful b/c capitalization is overlooked when looking for a match
        if (strcasecmp(path, "CSS") == 0) return "text/css";
        if (strcasecmp(path, "HTML") == 0) return "text/html";
        if (strcasecmp(path, "GIF") == 0) return "image/gif";
        if (strcasecmp(path, "ICO") == 0) return "image/x-icon";
        if (strcasecmp(path, "JPG") == 0) return "image/jpeg";
        if (strcasecmp(path, "JS") == 0) return "text/javascript";
        if (strcasecmp(path, "PHP") == 0) return "text/x-php";
        if (strcasecmp(path, "PNG") == 0) return "image/png";
    }
    //if there is no path, return NULL
    return NULL;
}

有可能做到这一点吗?有什么好处吗?或者我是在浪费时间吗?

正如评论所指出的,你不能。你能做的就是让它成为桌面驱动的,这可能是@Lambda Ninja想要让它更干燥的地方。像这样的

typedef struct pair_s {
    const char *first;
    const char *second;
} pair;

const char *lookup(const char *path)
{
    static pair content_types[] = {
        { "CSS", "text/css" },
        { "HTML", "text/html" },
        { "GIF", "image/gif" },
        { "ICO", "image/x-icon" },
        // ... etc.
        { "", "" }, // terminator
    };

    for (int i = 0; *content_types[i].first != '\0'; i++) {
        if (strcasecmp(path, content_types[i].first) == 0)
            return content_types[i].second;
    }

    return NULL;
}

正如评论所指出的,你不能。你能做的就是让它成为桌面驱动的,这可能是@Lambda Ninja想要让它更干燥的地方。像这样的

typedef struct pair_s {
    const char *first;
    const char *second;
} pair;

const char *lookup(const char *path)
{
    static pair content_types[] = {
        { "CSS", "text/css" },
        { "HTML", "text/html" },
        { "GIF", "image/gif" },
        { "ICO", "image/x-icon" },
        // ... etc.
        { "", "" }, // terminator
    };

    for (int i = 0; *content_types[i].first != '\0'; i++) {
        if (strcasecmp(path, content_types[i].first) == 0)
            return content_types[i].second;
    }

    return NULL;
}

因为C开关只能测试基元类型,所以需要将字符串映射到这些类型之一。 令人高兴的是,您要测试的字符串只有很少的字符可以放入int,因此您可以使用位运算符将字符组合成唯一值,可通过开关进行测试:

#define VAL_CSS  ( ((('C'<<8)|'S')<<8)|'S')
#define VAL_HTML ((((('H'<<8)|'T')<<8)|'M')<<8|'L')
#define VAL_GIF  ( ((('G'<<8)|'I')<<8)|'F')
#define VAL_ICO  ( ((('I'<<8)|'C')<<8)|'O')
#define VAL_JPG  ( ((('J'<<8)|'P')<<8)|'G')
#define VAL_JS   (   ('J'<<8)|'S')
#define VAL_PHP  ( ((('P'<<8)|'H')<<8)|'P')
#define VAL_PNG  ( ((('P'<<8)|'N')<<8)|'G')

const char* lookup(const char* path) { /* "ext" might be a better name than "path" */
  if (path != NULL)
    if (strlen(path) <= sizeof(uint32_t)) { /* check it'll fit */
      uint32_t val = 0;
      while (*path) 
        val = val<<8 | toupper(*path++); /* same as in #defines */

      switch (val) {
        case VAL_CSS:  return "text/css";        break;
        case VAL_HTML: return "text/html";       break;
        case VAL_GIF:  return "image/gif";       break;
        case VAL_ICO:  return "image/x-icon";    break;
        case VAL_JPG:  return "image/jpeg";      break;
        case VAL_JS:   return "text/javascript"; break;
        case VAL_PHP:  return "text/x-php";      break;
        case VAL_PNG:  return "image/png";       break;
      }
    }

  return NULL;
}

#define VAL_CSS((('C')因为C开关只能测试基元类型,所以需要将字符串映射到这些类型之一。
令人高兴的是,您要测试的字符串只有很少的字符可以放入int,因此您可以使用位运算符将字符组合成唯一值,可通过开关进行测试:

#define VAL_CSS  ( ((('C'<<8)|'S')<<8)|'S')
#define VAL_HTML ((((('H'<<8)|'T')<<8)|'M')<<8|'L')
#define VAL_GIF  ( ((('G'<<8)|'I')<<8)|'F')
#define VAL_ICO  ( ((('I'<<8)|'C')<<8)|'O')
#define VAL_JPG  ( ((('J'<<8)|'P')<<8)|'G')
#define VAL_JS   (   ('J'<<8)|'S')
#define VAL_PHP  ( ((('P'<<8)|'H')<<8)|'P')
#define VAL_PNG  ( ((('P'<<8)|'N')<<8)|'G')

const char* lookup(const char* path) { /* "ext" might be a better name than "path" */
  if (path != NULL)
    if (strlen(path) <= sizeof(uint32_t)) { /* check it'll fit */
      uint32_t val = 0;
      while (*path) 
        val = val<<8 | toupper(*path++); /* same as in #defines */

      switch (val) {
        case VAL_CSS:  return "text/css";        break;
        case VAL_HTML: return "text/html";       break;
        case VAL_GIF:  return "image/gif";       break;
        case VAL_ICO:  return "image/x-icon";    break;
        case VAL_JPG:  return "image/jpeg";      break;
        case VAL_JS:   return "text/javascript"; break;
        case VAL_PHP:  return "text/x-php";      break;
        case VAL_PNG:  return "image/png";       break;
      }
    }

  return NULL;
}


#定义VAL\u CSS((((‘C’你可以,用一个主要的黑客……我不推荐。我是一个初学者,不想为了它而变得太疯狂哈你不能,没有直接的平等比较。我相信你可以用一个更简单的方法,但不能用switch语句——你愿意吗?是的,这就是我试图实现一个切换!你可以,用一个主要的hack…我不推荐。我是一个初学者,不想为了它而变得太疯狂哈你不能,没有直接的相等比较。我相信你可以用一个更简单的方法,但不能用switch语句——你愿意吗?是的,这就是我试图实现的nt开关!大范围的ARCH具有
sizeof(int)==2
,因此您的代码必须使用
中的固定宽度整数类型。Type
uint32\u t
将始终具有
sizeof(uint32\u t)==4
。很好。我添加了一个sizeof(int)检查,使用long会更好,但我回答的要点是将字符串映射到可切换的表单,而不是生成可发布的代码。我是新来的,所以可能这不好。我将编辑代码。回答哪一个内容是唯一对我(imho)和你有好处的要点(因为这样可以节省你的时间),但确实存在,并且您的答案包含一些非关键性错误,大多数用户不会对您的代码进行复制粘贴。@yellowantphil我通常不会在切换中返回(我是函数底部的唯一退出者),因此我在开关返回中与请求者发生了一些冲突,我自己也需要中断。大范围的ARCH具有
sizeof(int)==2
,因此您的代码必须使用
中的固定宽度整数类型。Type
uint32_t
始终将具有
sizeof(uint32_t)==4
。这一点很好。我添加了对sizeof(int)的检查,使用long会更好,但我回答的要点是将字符串映射到可切换的表单,而不是生成可发布的代码。我是新来的,所以可能这不好。我将编辑代码。回答哪一个内容是唯一对我(imho)和你有好处的要点(因为这样可以节省你的时间),但确实存在,而且您的答案包含一些非关键性错误,并且大多数用户不会对您的代码进行复制粘贴。@yellowantphil我通常不会在开关中返回(我是函数底部的唯一出口),因此我在开关返回中与请求者发生冲突,我自己也需要中断。