How to use C ++ functions for cleaner use of i18n library when using gettext () directly with C

I would like to have an easy way to write code like:

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

but supports i18n. The following is an example of use gettext():

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

This can then be processed using xgettext to create a message catalog file that translators can use to create different versions. These additional files can be processed on the target system, allowing the user to interact in their preferred language.

I would like to write code something like this:

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

, xgettext, . << i18n::cout literal , .

- ?

+3
4

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, , .

, gettext,

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

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

, "" "_" gettext.

, " " API. , gettext API - , C.

+3

: "":)

, ? ICU , ++. , i18n, UTF-CPP UTF-8.
+1

, streambuf, . , , IOStreams ++ Langer Kreft, iostreams.

, , , :

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

The following transbuf class overrides the overflow function and translates the buffer each time it sees a new line.

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;
};

And here is an example of how this can be used:

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;
}    
+1
source

You want to say that you just need a different API? You can write a small wrapper, it should not be too complicated, and this will give you the opportunity to use the best API you can think of :)

0
source

Source: https://habr.com/ru/post/1710187/


All Articles