我在尝试将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;
}
有可能做到这一点,有什么好处还是我在浪费时间?
答案 0 :(得分:4)
正如评论所指出的那样,你不能。你可以做的是让它由表驱动,这可能是@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;
}
答案 1 :(得分:1)
因为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;
}
答案 2 :(得分:-3)
这看起来像是地图的候选人。
php中的例子:
$formats = array ("CSS" => "text/css", "HTML" => "text/html", etc);
//to use:
return $formats[path]; //returns text/css if path is equal to CSS