3

次のようなコードを簡単に記述できるようにしたいと考えています。

#include <iostream>
int main (){
    std::cout << "hello, world!\n";
}

しかし、それはi18nをサポートしています。を使用した例を次に示しgettext()ます。

#include <libintl.h>
#include <iostream>
int main (){
    std::cout << gettext("hello, world!\n");
}

これを xgettext で処理して、翻訳者がさまざまなバージョンを作成するために使用できるメッセージ カタログ ファイルを生成できます。これらの追加ファイルをターゲット システムで処理して、ユーザーが好みの言語で対話できるようにすることができます。

代わりに、次のようなコードを書きたいと思います。

#include <i18n-iostream>
int main (){
    i18n::cout << "hello, world!\n";
}

ビルド時に、引用符で囲まれた文字列が xgettext などのプログラムによって調べられ、ベース メッセージ カタログ ファイルが生成されます。 <<引数付きの演算子はi18n::cout、メッセージ カタログから使用するランタイム テキストをルックアップするためのキーとして文字列リテラルを取ります。

それはどこかに存在しますか?

4

4 に答える 4

3

ビルド時に、引用符で囲まれた文字列がxgettextなどのプログラムによって検査され、ベースメッセージカタログファイルが生成されます。<<引数i18n::coutを持つ演算子は、メッセージカタログから使用するランタイムテキストを検索するためのキーとして文字列リテラルを取ります。

単一のインスタンスのように文字列を変換しようとしますが、そうではありません/

重要なのは、このようなものは必要ないということです。のことを考える:

if(n=1)
    i18n::cout << "I need one apple"
else
    i18n::cout << "I need " << n << " apples" ;

「n=1」または「n!= 1」は英語でのみ機能するため、これが機能しない理由は、他の多くの言語には複数形があり、「Xリンゴが必要」をsignleインスタンスとして翻訳する必要があるためです。 。

gettextの扱い方を学ぶことをお勧めします。これは非常にシンプルで強力で、多くの人が考えていました。

もう1つのポイントは、通常はgettextを呼び出さないことですが、

#include <libintl.h>
#include <iostream>
#define _(x) gettext(x)

int main (){
    std::cout << _("hello, world!\n");
}

これにより、コードがはるかにクリーンになります。また、gettextエイリアスとして「_」を使用することは非常に「標準的な」機能です。

「より優れた」APIを作成する前に、その使用方法を学んでください。言うまでもなく、gettext APIは、Cだけでなく、多くの言語の事実上の標準です。

于 2009-06-10T18:43:30.770 に答える
1

個人的には this answerを使用しますが、テキストがストリームに書き込まれるときに、少し streambuf マジックを使用してこれを行うことができる場合があります。ただし、これに本当に興味がある場合は、 Langer と Kreft によるStandard C++ IOStreams and Localesを参照してください。これは iostream のバイブルです。

以下は、バッファに書き込まれたすべてが翻訳されること、および各行全体が完全に翻訳されることを前提としています。

std::string xgettext (std::string const & s)
{
  return s;
}

次の transbuf クラスは、「オーバーフロー」関数をオーバーライドし、改行が表示されるたびにバッファーを変換します。

class transbuf : public std::streambuf {
public:
  transbuf (std::streambuf * realsb) : std::streambuf (), m_realsb (realsb)
    , m_buf () {}

  ~transbuf () {
    // ... flush  m_buf if necessary
  }

  virtual std::streambuf::int_type overflow (std::streambuf::int_type c) {
    m_buf.push_back (c);
    if (c == '\n') {
      // We have a complete line, translate it and write it to our stream:
      std::string transtext = xgettext (m_buf);
      for (std::string::const_iterator i = transtext.begin ()
        ; i != transtext.end ()
        ; ++i) {
        m_realsb->sputc (*i);
        // ... check that overflow returned the correct value...
      }
      m_buf = "";
    }
    return c;
  }    

  std::streambuf * get () { return m_realsb; }

  // data
private:
  std::streambuf * m_realsb;
  std::string m_buf;
};

そして、これがどのように使用されるかの例です:

int main ()
{
  transbuf * buf = new transbuf (std::cout.rdbuf ());
  std::ostream trans (buf);

  trans << "Hello";  // Added to m_buf
  trans << " World"; // Added to m_buf
  trans << "\n";     // Causes m_buf to be written

  trans << "Added to buffer\neach new line causes\n"
           "the string to be translated\nand written" << std::endl;

  delete buf;
}    
于 2009-06-11T08:29:30.240 に答える
1

短い答えは「いいえ」です:)

真剣に、国際化のどの側面に興味がありますか? ICU はほとんどすべてを提供しますが、標準の C++ のようには感じません。UTF-8 でエンコードされた文字列を処理するための UTF-CPP など、いくつかの i18n 機能を提供する範囲の狭い他のライブラリがあります。

于 2009-06-10T17:52:40.000 に答える
0

別の API が欲しいということですか?小さなラッパーを書くことができますが、それほど難しくはなく、あなたが考えることができる最高の API を使用する可能性を与えるでしょう :)

于 2009-06-10T17:51:46.663 に答える