实现思路

  • 一个枚举存储语言类型
typedef enum {
    LANG_ZH,  // 中文
    LANG_EN,  // English
    LANG_MAX
} lang_t;
  • 一个全局变量存储 现在的语言类型。
static lang_t s_lang = LANG_EN;
  • get方法获取当前的语言类型
lang_t i18n_get_lang(void)
{
    return s_lang;
}
  • set方法设置当前语言类型
void i18n_set_lang(lang_t lang)
{
    if (lang < LANG_MAX)
        s_lang = lang;
}
  • 一个二维数组存储语言类型和真实文本(类比)

    • 第一个维度 存储 语言类型
    • 第二个维度 存储 文字key和文本value

    编译器在编译阶段,会做两件事:

    1. 把标识符替换成数字(枚举值或宏值)。

    2. 计算偏移量,把字符串的地址(指针)写入可执行文件的数据段(.rodata 或 .data)中对应的内存位置。

    3. enum { LANG_ZH = 0, LANG_EN = 1 };
      enum { settings_language = 0, settings_units = 1, ... };
      
static const char *table[LANG_MAX][STR_MAX] = {
    [LANG_ZH] = {
        [STR_ERROR_TIPS]    = "错误提示",
        [STR_TEMPERATURE]   = "温度"
    },
    [LANG_EN] = {
        [STR_ERROR_TIPS]    = "Error Tips",
        [STR_TEMPERATURE]   = "Temperature"
    },
};
  • 一个枚举列举当前拥有的文本key
typedef enum {
    STR_ERROR_TIPS,
    STR_TEMPERATURE,
    STR_DISTANCE,
    STR_TIME,
    STR_EMISSIVITY,
    STR_MAX
} str_key_t;
  • 对外提供获取文本的方法
const char *tr(str_key_t key)
{
    if (id >= STR_MAX)
        return "?";
    return table[s_lang][key];
}
  • 外部使用
//头文件引入i18n.h
int main(void)
{
    //获取文字
	char * error_tips = tr(STR_ERROR_TIPS);
    //切换语言
    i18n_set_lang(LANG_ZH);
    //再获取文字
    char * error_tips = tr(STR_ERROR_TIPS);
}