Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++, Multilanguage/Localisation support

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§);
like image 676
blubberbernd Avatar asked Mar 25 '11 13:03

blubberbernd


2 Answers

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.

like image 89
PAntoine Avatar answered Oct 22 '22 03:10

PAntoine


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.

like image 27
Éric Malenfant Avatar answered Oct 22 '22 01:10

Éric Malenfant