what's the best way to add multilanguage support to a C++ program?
If possible, the language should be read in from a plain text file containing something like key-value pairs (§WelcomeMessage§ "Hello %s!").
I thought of something like adding a localizedString(key) function that returns the string of the loaded language file. Are there better or more efficient ways?
//half-pseudo code
//somewhere load the language key value pairs into langfile[]
string localizedString(key)
{
//do something else here with the string like parsing placeholders
return langfile[key];
}
cout << localizedString(§WelcomeMessage§);
Simplest way without external libraries:
// strings.h
enum
{
LANG_EN_EN,
LANG_EN_AU
};
enum
{
STRING_HELLO,
STRING_DO_SOMETHING,
STRING_GOODBYE
};
// strings.c
char* en_gb[] = {"Well, Hello","Please do something","Goodbye"};
char* en_au[] = {"Morning, Cobber","do somin'","See Ya"};
char** languages[MAX_LANGUAGES] = {en_gb,en_au};
This will give you what you want. Obviously you could read the strings from a file. I.e.
// en_au.lang
STRING_HELLO,"Morning, CObber"
STRING_DO_SOMETHING,"do somin'"
STRING_GOODBYE,"See Ya"
But you would need a list of string names to match to the string titles. i.e.
// parse_strings.c
struct PARSE_STRINGS
{
char* string_name;
int string_id;
}
PARSE_STRINGS[] = {{"STRING_HELLO",STRING_HELLO},
{"STRING_DO_SOMETHING",STRING_DO_SOMETHING},
{"STRING_GOODBYE",STRING_GOODBYE}};
The above should be slightly easier in C++ as you could use the enum classes toString() method (or what ever it as - can't be bothered to look it up).
All you then have to do is parse the language files.
I hope this helps.
PS: and to access the strings:
languages[current_language][STRING_HELLO]
PPS: apologies for the half c half C++ answer.
Space_C0wb0w's suggestion is a good one. We currently use successfully use ICU for that in our products.
Echoing your comment to his answer: It is indeed hard to say that ICU is "small, clean, uncomplicated". There is "accidental" complexity in ICU coming from its "Java-ish" interface, but a large part of the complexity and size simply comes from the complexity and size of the problem domain it is addressing.
If you don't need ICU's full power and are only interested in "message translation", you may want to look at GNU gettext which, depending on your platform and licencing requirements, may be a "smaller, cleaner and less-complicated" alternative.
The Boost.Locale project is also an interesting alternative. In fact, its "Messages Formatting" functionality is based on the gettext model.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With