17

Вопрос по linux, c++ – Завершите C ++ i18n gettext () «Привет мир» пример

Я ищу полный i18ngettext() Привет мир пример. Я начал сценарий, основанный наУчебник по поддержке родного языка с использованием GNU gettext Г. Моханти. Я использую Linux и G ++.

Код:

cat >hellogt.cxx <<EOF
// hellogt.cxx
#include <libintl.h>
#include <locale.h>
#include <iostream>
#include <cstdlib>
int main (){
    char* cwd = getenv("PWD");
    std::cout << "getenv(PWD): " << (cwd?cwd:"NULL") << std::endl;
    char* l = getenv("LANG");
    std::cout << "getenv(LANG): " << (l?l:"NULL") << std::endl;
    char* s = setlocale(LC_ALL, "");
    std::cout << "setlocale(): " << (s?s:"NULL") << std::endl;
    std::cout << "bindtextdomain(): " << bindtextdomain("hellogt", cwd) << std::endl;
    std::cout << "textdomain(): " << textdomain( "hellogt") << std::endl;
    std::cout << gettext("hello, world!") << std::endl;
}
EOF
g++ -ohellogt hellogt.cxx
xgettext -d hellogt -o hellogt.pot hellogt.cxx
msginit --no-translator -l es_MX -o hellogt_spanish.po -i hellogt.pot
sed --in-place hellogt_spanish.po --expression='/#: /,$ s/""/"hola mundo"/'
sed --in-place hellogt_spanish.po --expression='s/PACKAGE VERSION/hellogt 1.0/'
mkdir -p ./es_MX/LC_MESSAGES
msgfmt -c -v -o ./es_MX/LC_MESSAGES/hellogt.mo hellogt_spanish.po
export LANG=es_MX
ls -l $PWD/es_MX/LC_MESSAGES/hellogt.mo
./hellogt
strace -e trace=open ./hellogt

Программа компилируется, текст извлекается, испанский файл создается, изменяется и создается в двоичном формате, но hellogt по-прежнему отображает английский. Трассировка не показывает никаких свидетельств поиска в текущем рабочем каталоге es_MX, а также никаких ссылок на каталог LC_MESSAGES.

  • Благодарю. Трассировка помогла определить, что код, который я имел, не смотрел на файлы, как я ожидал.

    от CW Holeman II
  • 3

    Вот описание gettext от проекта Fedora. Это просто следовать. Но это в

    с.

    http://fedoraproject.org/wiki/How_to_do_I18N_through_gettext

  • 11

    Вот описание файлов, созданных выше:

    cat >hellogt.cxx <<EOF
    // hellogt.cxx
    #include <libintl.h>
    #include <locale.h>
    #include <iostream>
    int main (){
        setlocale(LC_ALL, "");
        bindtextdomain("hellogt", ".");
        textdomain( "hellogt");
        std::cout << gettext("hello, world!") << std::endl;
    }
    EOF
    g++ -o hellogt hellogt.cxx
    xgettext --package-name hellogt --package-version 1.2 --default-domain hellogt --output hellogt.pot hellogt.cxx
    msginit --no-translator --locale es_MX --output-file hellogt_spanish.po --input hellogt.pot
    sed --in-place hellogt_spanish.po --expression='/"hello, world!"/,/#: / s/""/"hola mundo"/'
    mkdir --parents ./es_MX.utf8/LC_MESSAGES
    msgfmt --check --verbose --output-file ./es_MX.utf8/LC_MESSAGES/hellogt.mo hellogt_spanish.po
    LANGUAGE=es_MX.utf8 ./hellogt
    

    hellogt.cxx         C++ source file
    hellogt             Executable image
    hellogt.pot         Extracted text from C++ source file (portable object template)
    hellogt_spanish.po  Modified text for Spanish with translations added (using sed)
    es_MX.utf8/
     LC_MESSAGES/
       hellogt.mo       Binary translated text for Spanish used at run-time
    

  • 14

    Ваша проблема в том, что

    hellogt.mo находится не в том месте - ваша программа на самом деле не открывает его. Вы можете сказать это с помощьюstrace проследитьopen Системные вызовы:

    strace -e trace=open ./hellogt
    ...
    open("/tmp/.//es_MX/LC_MESSAGES/hellogt.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/tmp/.//es/LC_MESSAGES/hellogt.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    

    Вы можете повлиять на то, где gettext ищет каталоги сообщений с помощьюLOCPATH переменная окружения, но если вы переместите ее туда, где gettext пытается загрузить ее из вашего примера, сработает:

    mkdir -p es/LC_MESSAGES
    cp hellogt.mo es/LC_MESSAGES
    ./hellogt 
    hola mundo