Named locales not ok for locales without thousands separator

Benjamin Kosnik bkoz@redhat.com
Mon Jan 28 12:42:00 GMT 2002


> What does it mean for a locale to have "no" thousands separator?

I believe it's like this.

For Paolo, 

config/locale/numpunct_members.gnu.cc

    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc)
...
	  _M_thousands_sep = *(__nl_langinfo_l(THOUSEP, __cloc));

This is failing for him in fr_FR and it_IT but not de_DE because the 
underlying "C" locales are probably not complete for fr_FR and it_IT.
When the underlying named locales don't provide accurate info, the 
implementation as it stands now doesn't default to "C" locale info. (I 
believe this is as expected, but as this is an implementation issue 
perhaps it could change.)

Here's a simple "C" way to test:

#define _GNU_SOURCE 1
#include <locale.h>
#include <langinfo.h>

int main()
{
  __locale_t	loc;
  char p;
  const char* 	__s = "it_IT";
  loc = __newlocale(1 << LC_ALL, __s, 0);
  p = *(__nl_langinfo_l(THOUSEP, loc));
  __freelocale(loc);
  return 0;
}

You'll see p set to '0', not what you're probably expecting. You might 
want to talk to people on the "C" library list to see how you could help 
flesh out the it_IT locale data. (I've cc'd Ulrich, perhaps he can tell you.)

> The best way to make a test case would be to derive from std::numpunct<>
> and construct a locale using it.  Then you're not dependent on anybody's
> data files:

FYI, This works as you'd expect with only minor changes:

#include <locale>
#include <sstream>
#include <iostream>

struct testpunct : std::numpunct<char> 
{
  char do_thousands_sep() const { return '*'; }
  std::string do_grouping() const { return std::string("\002"); }
};

int main()
{
  std::locale loc(std::locale::classic(), new testpunct);
  std::stringstream str;
  str.imbue(loc);
  str << 12345;
  std::cout<< str.str();

  assert(str.str() == "1*23*45");
 
  return 0;
}



More information about the Libstdc++ mailing list