2014-12-26 1 views
1

Я использую следующий код для преобразования в верхнем регистре. Строки в моем программном обеспечении кодируются UTF8. Следующий код отлично работает в Windows, AIX и Linux (все 64 бит), однако он не работает в Solaris (SunOS 5.10 Generic_147440-01 sun4u sparc SUNW, SPARC-Enterprise).C++ Solaris Преобразование в верхнем регистре для специальных символов не работает

В Solaris специальные символы, такие как «ä», не преобразуются в их верхний регистр. Однако символы ASCII, такие как «a», «b» и т. Д., Преобразуются правильно в верхний регистр.

void String::MakeUpperUTF8() 
{ 
    WCHAR *pwstr = GetUnicode(); // Decode UTF8 encoded string to wide char string using iconv 

    if (!pwstr) 
    { 
     return; // return if decode fails. 
    } 

    std::locale::global(std::locale("")); 
    const std::ctype<WCHAR>& f = std::use_facet< std::ctype<WCHAR> >(std::locale()); // using std //ctype facet and std locale convert string to uppercase 

    f.toupper(pwstr, pwstr + wcslen(pwstr)); 
    char *strPos = SetUnicode(pwstr, -1); // encode string back to UTF8 

} 

Не могли бы вы помочь мне. Мне интересно, почему этот код не работает на Solaris.

+1

Что вы локаль по умолчанию? –

+0

Можете ли вы привести пример к результату, который у вас есть? например, если вы укажете вход «ä» (c3 a4), какой символ (и значение) у вас есть вместо «Ä» (c3 84)? – SHR

+0

Моей установкой по умолчанию является en_US.UTF-8. Ниже из положить команды локали на Солярис: LANG = en_US.UTF-8 LC_CTYPE = "en_US.UTF-8" LC_NUMERIC = "en_US.UTF-8" LC_TIME = "en_US.UTF-8" LC_COLLATE = "en_US.UTF-8" LC_MONETARY = "en_US.UTF-8" LC_MESSAGES = "en_US.UTF-8" LC_ALL = en_US.UTF-8 – user1565291

ответ

0

Спасибо, ребята, за вашу помощь.

Я решил проблему, используя следующий код. Стандартная фаза C++ не работает в Solaris. Поэтому я использовал towupper() Solaris API.

#if defined (SUN) || (__sun) 
     for (long i=0; i < nWLength; ++i) 
     { 
      pwstr[i] = towupper(pwstr[i]); 
     } 
    #else 
     const std::ctype<WCHAR>& f = std::use_facet< std::ctype<WCHAR> >(std::locale()); // using std ctype facet and std locale convert string to uppercase 
     f.toupper(pwstr, pwstr + nWLength); 
    #endif 

Спасибо, Sumit

0

Следующий код не с какой-либо местности, которую я пробовал, кроме C:

#include <locale> 
int main() { 
    std::locale::global(std::locale("")); 
    return 0; 
} 

Построенный с (-std=c++0x кажется, не имеет никакого эффекта, а также попытался -ansi с тем же результатом):

g++ -ggdb -Wall -std=c++0x solaris_locale.cc 
g++ -ggdb -Wall solaris_locale.cc 

Неисправности:

$ locale 
LANG=en_US.UTF-8 
LC_CTYPE="en_US.UTF-8" 
LC_NUMERIC="en_US.UTF-8" 
LC_TIME="en_US.UTF-8" 
LC_COLLATE="en_US.UTF-8" 
LC_MONETARY="en_US.UTF-8" 
LC_MESSAGES="en_US.UTF-8" 
LC_ALL= 
$ ./a.out 
terminate called after throwing an instance of 'std::runtime_error' 
    what(): locale::facet::_S_create_c_locale name not valid 
Abort (core dumped) 

Wo RKS:

$ LANG=C ./a.out 

GDB трассировку дает:

(gdb) bt 
#0 0xfe579265 in _lwp_kill() from /lib/libc.so.1 
#1 0xfe57218a in thr_kill() from /lib/libc.so.1 
#2 0xfe520fed in raise() from /lib/libc.so.1 
#3 0xfe4f875d in abort() from /lib/libc.so.1 
#4 0xfe7343d5 in __gnu_cxx::__verbose_terminate_handler() 
    at /builds/hudson/workspace/nightly-update/build/i386/components/gcc45/gcc-4.5.2/libstdc++-v3/libsupc++/vterminate.cc:93 
#5 0xfe7313c5 in __cxxabiv1::__terminate (
    handler=0xfe734280 <__gnu_cxx::__verbose_terminate_handler()>) 
    at /builds/hudson/workspace/nightly-update/build/i386/components/gcc45/gcc-4.5.2/libstdc++-v3/libsupc++/eh_terminate.cc:39 
#6 0xfe731422 in std::terminate() 
    at /builds/hudson/workspace/nightly-update/build/i386/components/gcc45/gcc-4.5.2/libstdc++-v3/libsupc++/eh_terminate.cc:49 
#7 0xfe731591 in __cxa_throw (obj=0x8061af0, tinfo=0xfe7652ec, 
    dest=0xfe725bb0 <~runtime_error>) 
    at /builds/hudson/workspace/nightly-update/build/i386/components/gcc45/gcc-4.5.2/libstdc++-v3/libsupc++/eh_throw.cc:83 
#8 0xfe71e927 in std::__throw_runtime_error (
    __s=0xfe735e18 "locale::facet::_S_create_c_locale name not valid") 
    at /builds/hudson/workspace/nightly-update/build/i386/components/gcc45/build/i86/i386-pc-solaris2.11/libstdc++-v3/include/bits/basic_string.h:233 
#9 0xfe72e790 in std::locale::facet::_S_create_c_locale ([email protected], 
    __s=0x8061254 "en_US.UTF-8") at c++locale.cc:66 
#10 0xfe735e18 in .LC11() from /usr/lib/libstdc++.so.6 
#11 0x00000000 in ??() 

машина информация:

$ uname -a 
SunOS os 5.11 11.1 i86pc i386 i86pc 
$ g++ -v 
Using built-in specs. 
COLLECT_GCC=g++ 
COLLECT_LTO_WRAPPER=/usr/gcc/4.5/lib/gcc/i386-pc-solaris2.11/4.5.2/lto-wrapper 
Target: i386-pc-solaris2.11 
Configured with: /builds/hudson/workspace/nightly-update/build/i386/components/gcc45/gcc-4.5.2/configure CC=/ws/on11update-tools/SUNWspro/sunstudio12.1/bin/cc CXX=/ws/on11update-tools/SUNWspro/sunstudio12.1/bin/CC --prefix=/usr/gcc/4.5 --mandir=/usr/gcc/4.5/share/man --bindir=/usr/gcc/4.5/bin --libdir=/usr/gcc/4.5/lib --sbindir=/usr/gcc/4.5/sbin --infodir=/usr/gcc/4.5/share/info --libexecdir=/usr/gcc/4.5/lib --enable-languages=c,c++,fortran,objc --enable-shared --with-gmp-include=/usr/include/gmp --with-mpfr-include=/usr/include/mpfr --without-gnu-ld --with-ld=/usr/bin/ld --with-gnu-as --with-as=/usr/gnu/bin/as CFLAGS='-g -O2 ' 
Thread model: posix 
gcc version 4.5.2 (GCC) 

Я бы предположил, Solaris C++ поддержка локали является неполной/сломана.

+0

Я подозреваю, что glibc locales! = Родные локали, а libstdC++ отлично работает с glibc. Возможно, вы можете попробовать тот же тест, связанный с glibc, а также с родным компилятором Sun. –

+0

@ н.м. Я использую версию 'g ++ ', которая поставляется с ОС, это единственный компилятор C/C++ на машине. Я тестировал 'setlocale (LC_ALL," ");' в программе C (не C++), построенный с помощью 'gcc' на одном компьютере и, похоже, работает (по крайней мере,' mbstowcs() 'работает нормально с UTF8). Я думаю, что установка glibc из источника не имеет отношения к этому вопросу. – kestasx

+0

Установка glibc из источника будет пустой тратой времени, поскольку glibc не может быть построен/использован на Solaris - он не поддерживает системные вызовы Solaris, а только Linux. – alanc