代码之家  ›  专栏  ›  技术社区  ›  CW Holeman II

如何利用C++的特性更简洁地使用I18N库,而不是直接使用GETTrEY()使用C

  •  3
  • CW Holeman II  · 技术社区  · 16 年前

    我希望有一个易于使用的方法来编写代码,如:

    #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 回复  |  直到 11 年前
        1
  •  3
  •   Artyom    16 年前

    在构建时,引用的字符串将由xgettext之类的程序检查,以生成基本消息目录文件<&书信电报;带有参数i18n::cout的运算符将采用字符串文字作为键,以查找要从消息目录中使用的运行时文本。

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

    所以为什么这是行不通的,因为“n=1”或“n=1“只适用于英语,许多其他语言有一个以上的复数形式,也需要翻译“我需要X苹果”作为单数实例。

    我建议你只要学会处理gettext,它相当简单和强大,很多人都想过。

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

    这使得代码更加简洁,而且使用“216;”作为gettext别名也是相当“标准”的特性。

        2
  •  1
  •   Nemanja Trifunovic    16 年前

    简单的回答是“不”:

    说真的,你对国际化的哪些方面感兴趣?ICU提供了几乎所有的东西,但感觉不像标准C++。还有一些范围较小的库提供了一些i18n功能,即用于处理UTF-8编码字符串的UTF-CPP。

        3
  •  1
  •   Community Mohan Dere    8 年前

    我个人会同意这个 answer Standard C++ IOStreams and Locales 由兰格和克里夫特所著,这是约瑟姆的圣经。

    以下假设写入缓冲区的所有内容都将被翻译,并且每一整行都可以被完全翻译:

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

    下面的transbuf类重写“overflow”函数并

    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;
    }    
    
        4
  •  0
  •   soulmerge    16 年前