所以,我正在努力将我的C ++应用程序翻译成多种语言。我目前正在使用的是:
#define TR(x) (lookupTranslatedString( currentLocale(), x ))
wcout << TR(L"This phrase is in English") << endl;
翻译来自CSV文件,该文件将英文字符串映射到翻译后的字符串。
"This phrase is in English","Nasa Tagalog itong pagsabi"
这是简化的,但这是基本的想法。
我的问题是关于生成需要翻译的英语短语列表。我只需要包含所有英语短语和空白翻译短语的CSV。我希望可以在编译时或运行时生成此列表。在编译时我正在考虑这样的事情:
#define TR(x) \
#warning x \
(lookupTranslatedString( currentLocale(), x ))
然后可能会解析编译日志或其他东西。这似乎不太好用。
在运行时也会很棒。我正在考虑启动应用程序并使用隐藏的命令来转储英文CSV。我已经看到类似的方法用于使用全局变量向中央列表注册命令。它可能看起来像这样:
class TrString
{
public:
static std::set< std::wstring > sEnglishPhrases;
TrString( std::wstring english_phrase ) { sEnglishPhrases.insert( english_phrase ); }
};
#define TR(x) do {static TrString trstr(x);} while( false ); (lookupTranslatedString( currentLocale(), x ));
我知道上面的代码存在两个问题。我怀疑它是否编译,但更重要的是,为了生成所有英语短语的列表,我需要在访问sEnglishPhrases之前点击每个代码路径。
看起来我最终会编写一个小的解析器来读取我的所有代码并查找TR字符串,这并不是那么难。我只是希望学习更多关于C ++的知识,如果有更好的方法可以做到这一点。
答案 0 :(得分:2)
您可以构建一个快速脚本来解析文件并删除所需内容。
awk '/TR\(L"[^"]*")/ {print}' plop.c
如果你需要稍微复杂的东西,那么perl就是你的朋友。
答案 1 :(得分:1)
我想你差不多了。采取最后的想法:
class TrString
{
public:
static std::set< std::string > sEnglishPhrases;
std::string phrase;
TrString(const std::string& english_phrase ):phrase(english_phrase)
{ sEnglishPhrases.insert( english_phrase ); }
friend ostream &operator<<(ostream &stream, const TrString& o);
};
ostream &operator<<(ostream &stream, const TrString& o)
{
stream << lookupTranslatedString( currentLocale(), o.phrase);
return stream;
}
#define TR(x) ( TrString(x) )
// ...
std::cout << TR("This phrase is in English") << std::endl;
正如您所说,您确实需要在每个TR()
语句上运行代码,但您可以配置单元测试框架来执行此操作。
我的另一种方法是使用上面的TrString类为每个模块创建静态变量:
// unnamed namespace gives static instances
namespace
{
TrString InEnglish("This phrase is in English");
// ...
}
现在你只需要链接另一个main()
来打印掉TrString :: sEnglishPhrases
答案 2 :(得分:0)
您正在寻找的内容与GNU gettext的内容非常相似。请特别注意xgettext工具。