-->

How to support multiple language in a Linux C/C++

2020-07-20 04:05发布

问题:

For example, in this simplest hello world program:

#include <iostream>
int main()
{
    std::cout<<"Hello World!"<<std::endl;
    return 0;
}

I'd like to see French if user's environment LANG is set to fr_FR, it might looks like:

$ ./a.out
Hello World!

$ LANG=fr_FR.utf8
$ ./a.out
Bonjour tout le monde!

Is there a guideline of how to archieve this in Linux?

回答1:

The key is to use "resources" (one per-language, configured to be read at runtime) vs. hard-coding strings. GUI frameworks like Qt and GTK+ make this (relatively) easy.

Here's a link to the Pango" library used by GTK+ (but not, emphatically, exclusive to GTK+):

  • http://www.pango.org/

Here's a tutorial on using Pango:

  • http://x11.gp2x.de/personal/google/

And here's a tutorial on "gettext()" (which, I believe, Pango uses):

  • http://inti.sourceforge.net/tutorial/libinti/internationalization.html


回答2:

Two questions here.

  1. You can easily make your program internationalized/localized using the Gettext library.

  2. You can check the user's environment variables using either the standard function `getenv()’:

    const char *langcode = getenv("LANG");

or some implementations (I believe Linux and Mac OS X included) support a 3-argument main function:

int main(int argc, char **argv, char **envp)
{
    char **e;
    char *langcode;
    for (langcode = NULL, e = envp; e != NULL; e++)
    {
        if (strstr(*e, "LANG") != NULL)
        {
             langcode = strchr(*e, '=') + 1;
             break;
        }
    }

    printf("Language: %s\n", langcode);
}


回答3:

You probably won't want to do this in simple program, but if your program is large enough, you can use GNU gettext, which can be found at http://www.gnu.org/software/gettext/ . Then, you supply your program with the text files, and then use printf (_("Some string\n")) to output localized string.



回答4:

Just found a tutorial that I can easily follow: http://fedoraproject.org/wiki/How_to_do_I18N_through_gettext

Here is my new code

#include <iostream>
#include <libintl.h>
#include <locale.h>

int main()
{
    setlocale(LC_ALL, "");
    bindtextdomain("helloworld", "/usr/share/locale");
    textdomain("helloworld");

    std::cout<<gettext("Hello World!")<<std::endl;
    return 0;
}

Then creates pot file

mkdir po
xgettext --package-name helloworld --package-version 1.0 -d helloworld -o po/helloworld.pot -s a.cpp

Generates mo file

msginit --no-translator --locale fr_FR --output-file po/helloworld.po --input po/helloworld.pot
sed --in-place po/helloworld.po --expression='/"Hello World!"/,/#: / s/""/"Bonjour tout le monde!"/'
msgfmt po/helloworld.po -o po/helloworld.mo
sudo cp po/helloworld.mo /usr/share/locale/fr/LC_MESSAGES/

Here is the output

[deqing@hdell]~/work/sty$ ./helloworld
Hello World!
[deqing@hdell]~/work/sty$ LANG=fr_FR.utf-8
[deqing@hdell]~/work/sty$ ./helloworld
Bonjour tout le monde!


回答5:

For c++, if you can use Qt library, it has a good support for localization. For details take a look into their page for the internalization.

Next pseudo-example shows how to load the translation files, and set the locale :

int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);

     QTranslator qtTranslator;
     qtTranslator.load("qt_" + QLocale::system().name(),
             QLibraryInfo::location(QLibraryInfo::TranslationsPath));
     app.installTranslator(&qtTranslator);

     QTranslator myappTranslator;
     myappTranslator.load("myapp_" + QLocale::system().name());
     app.installTranslator(&myappTranslator);

     ...
     return app.exec();
 }


标签: c++ c linux locale