如何在运行时向嵌入式应用程序添加多种语言选择?

时间:2017-07-03 13:17:22

标签: c embedded

目前我在编译时选择语言,如下所示:

#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了?

4 个答案:

答案 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;
}