该函数本身没有任何问题,但 可能其中一个有问题:
不幸的是,这两个都包含在问题中未包含的代码中,所以现在是假设。
在第一种情况下,如果您传递的不是 C 字符串(例如 NULL),您可能会发现 strcmp 会导致问题。
在第二种情况下,因为您返回的是字符串文字,所以任何修改它的尝试都将是未定义的行为。我希望您返回指向 const 数据的指针这一事实可以防止这种情况发生,但如果不看到周围的代码就很难说。
而且,顺便说一句,虽然不是真正解决您的问题的一部分:虽然我通常赞成使用数据驱动的代码,例如您使用选项表,但它存在许多问题。
首先,表中的字符串最好标记为const,因为它们是不应更改的字符串文字。
我看到您将字符串返回为const,但将项目本身设为const 有时可以为编译器提供更多优化代码的余地。事实上,尽可能多的应该是const,除非有迫切的理由允许调用者更改它们。
其次,由于表永远不会改变,因此最好使用静态存储持续时间,这样每次输入函数时都不会重新创建数组(一个好的优化器可能会发生这种情况,但强制它更安全) .
第三,当不需要时,您的代码中有神奇的数字17。这意味着,如果您添加一种语言,则需要更改 三项 项(数组、数组的大小和处理数组的循环),这意味着可以得到三项不同步并给您带来麻烦。
考虑到所有这些点的更好方法可能是:
const char *welcome(const char *language) {
static const struct {
const char *language;
const char *greeting;
} list[] = {
{ "czech", "Vitejte" },
{ "danish", "Velkomst" },
{ "dutch", "Welkom" },
{ "english", "Welcome" },
{ "estonian", "Tere tulemast" },
{ "finnish", "Tervetuloa" },
{ "flemish", "Welgekomen" },
{ "french", "Bienvenue" },
{ "german", "Willkommen" },
{ "irish", "Failte" },
{ "italian", "Benvenuto" },
{ "klingon", "nuqneH" },
{ "latvian", "Gaidits" },
{ "lithuanian", "Laukiamas" },
{ "polish", "Witamy" },
{ "spanish", "Bienvenido" },
{ "swedish", "Valkommen" },
{ "welsh", "Croeso" }
};
for (int i = 0; i < sizeof(list) / sizeof(*list); i++) {
if (strcmp(language, list[i].language) == 0) {
return list[i].greeting;
}
}
return "Welcome";
}
使用该方案,您可以添加或删除语言,无需更改其他代码。
您会看到我已将 english 紧跟在 dutch 之后(由于我的 CDO 性质(a)),因为您的其余条目已排序,但它 可能是因为(例如)它是最有可能传入的值,所以您将它放在顶部。如果确实有原因,请随意将其更改回来。
代码的格式也很好,因此维护人员可以轻松辨别发生了什么。
另一个你可能想要检查的可能性是它是否需要数据驱动,因为它是一个简单的字符串到字符串的转换。您同样可以编写格式良好的代码,而无需数据驱动,例如:
const char *welcome(const char *language) {
if (strcmp(language, "czech" ) == 0) return "Vitejte" ;
if (strcmp(language, "danish" ) == 0) return "Velkomst" ;
if (strcmp(language, "dutch" ) == 0) return "Welkom" ;
if (strcmp(language, "english" ) == 0) return "Welcome" ;
if (strcmp(language, "estonian" ) == 0) return "Tere tulemast" ;
if (strcmp(language, "finnish" ) == 0) return "Tervetuloa" ;
if (strcmp(language, "flemish" ) == 0) return "Welgekomen" ;
if (strcmp(language, "french" ) == 0) return "Bienvenue" ;
if (strcmp(language, "german" ) == 0) return "Willkommen" ;
if (strcmp(language, "irish" ) == 0) return "Failte" ;
if (strcmp(language, "italian" ) == 0) return "Benvenuto" ;
if (strcmp(language, "klingon" ) == 0) return "NuqneH" ;
if (strcmp(language, "latvian" ) == 0) return "Gaidits" ;
if (strcmp(language, "lithuanian") == 0) return "Laukiamas" ;
if (strcmp(language, "polish" ) == 0) return "Witamy" ;
if (strcmp(language, "spanish" ) == 0) return "Bienvenido" ;
if (strcmp(language, "swedish" ) == 0) return "Valkommen" ;
if (strcmp(language, "welsh" ) == 0) return "Croeso" ;
return "Welcome";
}
或者,如果您不喜欢输入所有常见的东西,您可以使用以下内容:
const char *welcome(const char *language) {
#define XLAT(FROM, TO) if (strcmp(language, FROM) == 0) return TO
XLAT("czech", "Vitejte");
XLAT("danish", "Velkomst");
XLAT("dutch", "Welkom");
XLAT("english", "Welcome");
XLAT("estonian", "Tere tulemast");
XLAT("finnish", "Tervetuloa");
XLAT("flemish", "Welgekomen");
XLAT("french", "Bienvenue");
XLAT("german", "Willkommen");
XLAT("irish", "Failte");
XLAT("italian", "Benvenuto");
XLAT("latvian", "Gaidits");
XLAT("lithuanian", "Laukiamas");
XLAT("polish", "Witamy");
XLAT("spanish", "Bienvenido");
XLAT("swedish", "Valkommen");
XLAT("welsh", "Croeso");
#undef XLAT
return "Welcome";
}
但请确保您注意有关类似函数的宏的警告。我很少推荐它们,但它们在这种情况下还可以,因为它们控制得很好。
例如,当在不带大括号的 if 或 while 语句中使用时,它们可能会导致问题,除非您明确地满足这一要求(臭名昭著的 #define X(Y) do { something with Y } while(0),您无疑可以在本网站的其他地方找到)。
(a) 强迫症,但该死的顺序是正确的:-)