2009-09-14 24 views
1

我想本地化一個我已經編寫的程序。它相當大(幾乎有5萬行),理想情況下我想要一個系統讓我(程序員)做最少量可能的工作,並且沒有重大改變 - 如果可能的話,根本沒有。C++:如何本地化一個已經編寫的程序

我看着gettext的(),喜歡它了很多,但它是我不清楚它如何轉化的字符串,如這些:

const char *Colors[] = { 
{ "Red" }, 
{ "Blue" }, 
{ "Yellow" }, 
.... 
}; 

這是非常共同在我的計劃。這裏更換帶有gettext(「紅色」)的「紅色」顯然不起作用。

所以我想我會做類似OutputFunction(gettext(Colors [Id])),但是我怎樣才能得到一個字符串列表本地化?我懷疑任何程序都足夠聰明,可以靜態地從本地化列表中獲得「紅色」,「藍色」,「黃色」。

因爲它基本上是一個服務器,所以沒有必要在沒有重新編譯的情況下改變語言(我可以在沒有任何重大問題或煩惱的情況下爲每種支持的語言編譯它),我想到了C++ 0x的constexpr,完美!它可以在數組/等工作,我很容易得到一個字符串列表本地化在編譯時間..太糟糕了,沒有編譯器實現它呢。

將所有字符串更改爲ID不是一個選項,因爲它需要大量的工作,尤其是爲每個新字符串創建一個新的ID會讓人討厭。這同樣適用於將所有數組轉換爲其他數組。

那麼,有什麼想法? :/

+1

不是說這對你有幫助,但是就像旁邊一樣,即使'constexpr'可用,我也懷疑它會幫助你。 'constexpr'只有在函數本身可以在編譯時進行評估的情況下才能正常工作,所以如果修改過的'gettext'是基於打開和讀取本地化文件的,那麼無論如何你都無法使它成爲'constexpr'(因爲打開&讀取文件不能在編譯時完成)。鑑於大多數這樣的系統都是基於這種方式的,我懷疑'constexpr'確實會有幫助。 – GRB 2009-09-14 01:49:27

回答

1

經過很多玩弄gettext()和xgettext後,我想我找到了一種方式我自己(抱歉onebyone,但我不喜歡你的方法..必須有數百這樣的數組,我必須導入所有這些在main()中,這是很多extern和大量額外的工作:/)。

不管怎麼說,這是我認爲這在理論上可以做到(我還沒有嘗試尚未實際轉換,但我不明白爲什麼它不會工作)

兩個#定義的:

#define _ gettext 
#define __(x) x 

然後使用_實際上翻譯和__簡單地標識字符串爲「被翻譯成」:

const char *Colors[] = { 
{ __("Red") }, 
{ __("Blue") }, 
{ __("Yellow") }, 
.... 
}; 

void PrintColor(int id) { 
    cout << _("The color is: ") << _(Colors[id]); 
} 

然後運行:

xgettext -k_ -k__ *.cpp 

,你會得到下面的.po文件:

#: test.cpp:2 
msgid "Red" 
msgstr "" 

#: test.cpp:3 
msgid "Blue" 
msgstr "" 

#: test.cpp:4 
msgid "Yellow" 
msgstr "" 

#: test.cpp:9 
msgid "The color is: " 
msgstr "" 

所以,你用__(或任何其他名稱,並不真正的問題)作爲一個「虛擬功能」只是讓了xgettext知道該字符串需要翻譯,並_實際調用gettext()。

如果您使用字符串調用_,那麼字符串也將被標記爲要被翻譯,如果您使用變量,數組調用它,則無論如何它都會被xgettext忽略。

太棒了!現在我所要做的就是通過5萬億個文件並添加下劃線,就好像我是一隻猴子一樣:/

2

爲了您的具體的例子,我可能會嘗試這樣的:

// presumably globals 
const char *Colors_en[] = { 
{ "Red" }, 
{ "Blue" }, 
{ "Yellow" }, 
.... 
}; 
const char *Colors[] = {0}; 

// in main() 
gettextarray(Colors_en, Colors, sizeof(Colors_en)/sizeof(char*)); 

gettextarray調用gettext的每個輸入和寫入輸出。我認爲它可以作爲對std :: transform的調用來實現。你可以通過一些模板欺騙來避免大小參數。

另一種選擇是在任何顏色字符串即將使用(顯示或附加到字符串以供顯示)時調用gettext。這意味着改變更多的代碼,但並不要求main()在執行任何可能使用它們的任何事情之前先轉換程序中的每一組字符串。

如果你不想做的主要工作,你能做到這一點在使用字符串中的代碼,這樣的事情:

if (Colors[0] == 0) 
    gettextarray(Colors_en, Colors, sizeof(Colors_en)/sizeof(char*)); 

或者,如果您的應用程序是多線程的,考慮pthread_once或相當於您使用的線程API。

相關問題