目前我在编译时选择语言,如下所示:
#define FRENCH_LANG 0
#define ZULU_LANG 0
#define ENGLISH_LANG 1
#if(FRENCH_LANG == 1)
const char PROMPT_HELLO[] = "Bonjour";
const char PROMPT_THANKS[] = "Merci";
#elif(ZULU_LANG == 1)
const char PROMPT_HELLO[] = "Sawubona";
const char PROMPT_THANKS[] = "Ngiyabonga";
#elif(ENGLISH_LANG == 1)
const char PROMPT_HELLO[] = "Hello";
const char PROMPT_THANKS[] = "Thanks";
#endif
int main(int argc, char *argv[]) {
printf("%s\r\n", PROMPT_HELLO);
printf("%s\r\n", PROMPT_THANKS);
return 0;
}
我想更改我的代码,以便编译所有语言,用户可以选择所需的语言。 有没有一种聪明的方法可以做到这一点,这样我就不必复制或复制我的printf了?
答案 0 :(得分:6)
作为Some programmer dude答案的变体,您可以使用结构和保持当前语言的全局指针。那么不需要枚举,并且通过删除一个间接级别来更容易访问:
this.connection =
DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
当然有许多事情需要改进,但它可以是体面的。在初始化程序中重复成员名称(struct strings {
const char *hello;
const char *thanks;
};
const struct strings strings_english = {
.hello = "Hello",
.thanks = "Thanks",
};
const struct strings strings_zulu = {
.hello = "Sawubona",
.thanks = "Ngiyabonga",
};
const struct strings_french = {
.hello = "Bonjour",
.thanks = "Merci",
};
static const struct strings *current_strings = NULL;
void set_language(const char *code)
{
if(strcmp(code, "en") == 0)
current_strings = &strings_english;
...
}
int main(void)
{
set_language("en");
printf("%s\n", current_strings->hello);
return 0;
}
等)使得验证更容易,如果/当您采取步骤构建工具来提取/更新文本时,也可能使生活更轻松。有时翻译不是由程序员完成的,而且需要一种方法来将文本输入和输出程序。
答案 1 :(得分:3)
您可以使用字符串数组数组来执行此操作:
// Define the language indexes
#define FRENCH_LANG 0
#define ZULU_LANG 1
#define ENGLISH_LANG 2
// Number of strings translated
#define NUMBER_OF_STRINGS 2
// The translated strings
#define PROMPT_HELLO 0
#define PROMPT_THANKS 1
// Define the strings
const char *languages[3][NUMBER_OF_STRINGS] = {
// French
{
"Bonjour",
"Merci"
},
// Zulu
{
"Sawubona",
"Ngiyabonga"
},
// English
{
"Hello",
"Thanks"
}
};
然后将变量设置为您可以执行的语言索引之一,例如
int language = ENGLISH_LANG;
...
printf("%s", languages[language][PROMPT_HELLO]);
另一个可能的解决方案,与上面非常类似,是使用结构的数组,其中结构的每个成员都是该语言的字符串:
struct translation_strings
{
const char *hello;
const char *thanks;
};
// Define the language indexes
#define FRENCH_LANG 0
#define ZULU_LANG 1
#define ENGLISH_LANG 2
struct translation_strings languages[3] = {
// French
{
"Bonjour",
"Merci"
},
// Zulu
{
"Sawubona",
"Ngiyabonga"
},
// English
{
"Hello",
"Thanks"
}
};
...
printf("%s", languages[language].hello);
请注意,如果您希望在应用程序中拥有大量字符串,则此将占用大量空间。它将有效地使程序的数据大小增加三倍。
如果目标是具有可能的文件系统的更大的嵌入式系统,那么可能有更好的方法来处理翻译。例如,如果您的目标是Linux系统,那么我建议您查看GNU gettext系统来处理翻译(它是基于Linux的系统的事实标准)。
答案 2 :(得分:0)
typedef enum
{
e_FRENCH = 0,
e_ZULU = 1,
e_ENGLISH = 2
} language;
const char* greetings[] = {
"Bonjour", /* french */
"Sawubona", /* zulu */
"Hello", /* english */
};
void greet_in(language l)
{
printf("%s", greetings[(int) l]);
}
int main()
{
greet_in(e_ENGLISH); // prints "Hello"
return 0;
}
然后,您可以从配置文件或language
中读取stdin
的值。
答案 3 :(得分:-1)
如果您不想更改所有代码,只需要初始化,则可以使用char指针。指针与之前的consts具有相同的名称。当然可以使用更智能的初始化,这只是一个例子。
lang.h
------
extern const char *PROMPT_HELLO;
extern const char *PROMPT_THANKS;
void set_lang(int lang);
lang.c
------
const char *PROMPT_HELLO;
const char *PROMPT_THANKS;
void set_lang(int lang)
{
if (lang==FRENCH_LANG)
{
PROMPT_HELLO = "Bonjour";
PROMPT_THANKS = "Merci";
}
else if (lang==ZULU_LANG)
{
PROMPT_HELLO = "Sawubona";
PROMPT_THANKS = "Ngiyabonga";
}
else if (lang==ENGLISH_LANG)
{
PROMPT_HELLO = "Hello";
PROMPT_THANKS = "Thanks";
}
}
最后,程序代码不会改变:
int main(int argc, char *argv[]) {
set_lang(ZULU_LANG);
printf("%s\r\n", PROMPT_HELLO);
printf("%s\r\n", PROMPT_THANKS);
return 0;
}