Hi,I have some problem with locales on FreeBSD 6.3. The attached test case fails with uncaught std::runtime_error exception:
shell::wilx:~/tmp> locale LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_ALL= shell::wilx:~/tmp> ./codecvt_test "abcdŠ<" terminate called after throwing an instance of 'std::runtime_error' what(): locale::facet::_S_create_c_locale name not valid zsh: abort (core dumped) ./codecvt_test "abcdŠ<" shell::wilx:~/tmp> locale -a |grep en_US.UTF-8 en_US.UTF-8I don't understand why? It works without change on both Windows and Gentoo/Linux.
-- VH
// codecvt_test.cpp : Defines the entry point for the console application. // #include <string> #include <locale> #include <cwctype> #include <iostream> #include <vector> #include <cassert> std::wstring towstring(const std::string& src) { std::wstring outstr; typedef std::codecvt<wchar_t, char, std::mbstate_t> CodeCvt; std::locale loc (""); const CodeCvt & cdcvt = std::use_facet<CodeCvt>(loc); std::mbstate_t state = {0}; char const * const from_first = src.c_str (); size_t const from_size = src.size (); char const * const from_last = from_first + from_size; char const * from_next = from_first; // XXX: Intentionally allocate only half the size of the input. std::vector<wchar_t> dest (from_size / 2); wchar_t * to_first = &dest.front (); size_t to_size = dest.size (); wchar_t * to_last = to_first + to_size; wchar_t * to_next = to_first; CodeCvt::result result; size_t converted = 0; while (true) { result = cdcvt.in ( state, from_first, from_last, from_next, to_first, to_last, to_next); if ((result == CodeCvt::partial || result == CodeCvt::ok) && from_next != from_last) { to_size = dest.size () * 2; dest.resize (to_size); converted = to_next - to_first; to_first = &dest.front (); to_last = to_first + to_size; to_next = to_first + converted; continue; } else if (result == CodeCvt::ok && from_next == from_last) break; else { assert (0); break; } } converted = to_next - to_first; outstr.assign (dest.begin (), dest.begin () + converted); return outstr; } int main (int argc, char * argv[]) { if (argc < 2) { std::cerr << "codecvt_test string\n"; return 1; } std::string str (argv[1]); std::wstring wstr = towstring (str); std::wcout << std::hex; for (std::wstring::const_iterator it = wstr.begin (); it != wstr.end (); ++it) std::wcout << static_cast<unsigned>(*it) << " "; std::wcout << "\n"; std::wcout.imbue (std::locale ("")); std::wcout << wstr << std::endl; return 0; }
signature.asc
Description: OpenPGP digital signature