C++ – I18n C++ hello world with plurals

cgettextinternationalization

Complete C++ i18n gettext() “hello world” example has C++ code that works for a simple fixed string. I am now looking for an example program that works with plurals. This example code displays six lines. Only one is correct in English. It does not handle the plurals correctly.

cat >helloplurals.cxx <<EOF
// hellopurals.cxx
#include <libintl.h>
#include <locale.h>
#include <iostream>
#include <stdio.h>
int main (){
    setlocale(LC_ALL, "");
    bindtextdomain("helloplurals", ".");
    textdomain( "helloplurals");
    for (int ii=0; ii<5; ii++)
        printf (gettext("Hello world with %d moon.\n"), ii);
}
EOF
g++ -o helloplurals helloplurals.cxx
./helloplurals

GNU gettext() for plural forms describes various ways that languages handle plurals for example:

  • Korean – no pluals
  • English – two forms, singular used for one only
  • French – two forms, singular used for zero and one
  • Polish – three forms, special case for one and some numbers ending in 2, 3, or 4

My expectation is that the code will be able to work (given message catalogs) specifically for all of the above cases and several more variations not listed here. The correct output when it is executed with English would be:

Hello world with 0 moons.
Hello world with 1 moon.
Hello world with 2 moons.
Hello world with 3 moons.
Hello world with 4 moons.

Best Answer

I'm not sure what you want. If it is slight modification of your example that give your wanted output, just replace the printf line by

printf(ngettext("Hello world with %d moon\n", "Hello world with %d moons\n", ii), ii);

but as it is a trivial modification of unwind's answer and the gettext documentation has the very similar example,

printf (ngettext ("%d file removed", "%d files removed", n), n);

I wonder if it is really what you wanted. If you want to use gettext with a more C++ syntax, you'll have to look for libraries like Boost::Format.