vswprintf не работает для определенных кодовых точек Unicode в Mac OS X

Я получаю необъяснимые сбои (возвращаемое значение -1) от vswprintf с использованием GCC и Mac OS X (протестировано с gcc 4.0 и 4.2.1 под Mac OS X 10.6 и 10.8. GCC под Linux не пострадавшие. Visual Studio также не пострадавших).

Чтобы продемонстрировать проблему, я минимально адаптировал пример из Вот так что распечатывает vswprintfвозвращаемое значение:

/* vswprintf example */
#include <stdio.h>
#include <stdarg.h>
#include <wchar.h>

void PrintWide ( const wchar_t * format, ... )
{
wchar_t buffer[256];
va_list args;
va_start ( args, format );
int res = vswprintf ( buffer, 256, format, args );
wprintf ( L"result=%d\n", res );
fputws ( buffer, stdout );
va_end ( args );
}

int main ()
{
wchar_t str[] = L"test string has %d wide characters.\n";
PrintWide ( str, wcslen(str) );
return 0;
}

Из моих тестов выясняется, что в зависимости от значения str, vswprintf иногда потерпит неудачу. Примеры:

wchar_t str[] = L"test string has %d wide characters.\n"; // works
wchar_t str[] = L"ßß® test string has %d wide characters.\n"; // works
wchar_t str[] = L"日本語 test string has %d wide characters.\n"; // FAILS
wchar_t str[] = L"Π test string has %d wide characters.\n"; // FAILS
wchar_t str[] = L"\u03A0 test string has %d wide characters.\n"; // FAILS

Похоже, что любые строки, которые включают символы с кодами Unicode выше 0xff вызовет эту проблему. Кто-нибудь может пролить свет на то, почему это происходит? Кажется, это слишком большая проблема, чтобы не было замечено раньше!

2

Решение

Если вы установите язык, это должно быть хорошо. Чтобы подобрать переменную среды, вы можете сделать это:

setlocale(LC_CTYPE, "");   // include <locale.h>

или установите это явно. Это потому, что все выходные функции должны знать, какую кодировку использовать.

OS X не может выполнить vswprintf вообще, пока Linux запускает его (хотя символы будут неправильными, если будут напечатаны).

Вот соответствующий раздел документации glibc:

   If  the  format  string contains non-ASCII wide characters, the program
will only work correctly if the LC_CTYPE category of the current locale
at  run time is the same as the LC_CTYPE category of the current locale
at compile time.  This is because the wchar_t representation  is  plat‐
form-  and  locale-dependent.   (The  glibc  represents wide characters
using their Unicode (ISO-10646) code point, but other  platforms  don't
do  this.
0

Другие решения

Других решений пока нет …