2013-03-15 6 views
2

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

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

/* 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 вызовет эту проблему. Может ли кто-нибудь пролить свет на то, почему это происходит? Кажется, слишком большой вопрос, которого раньше не было замечено!

+0

кодировка исходного файла соответствует ли кодированию ожидаемого в строках? – Dmitri

+0

Я бы ожидал, что вызов 'fputws' завершится неудачей в стандартном' 'C '' локали для символов вне диапазона, но 'vswprintf' должен работать. –

+0

В заголовке нет «GCC vswprintf». Причина, по которой GCC на GNU/Linux ведет себя по-разному с GCC на Mac OS X, заключается в том, что 'vswprintf' не имеет ничего общего с GCC, она предоставляется библиотекой C операционной системы,' libc' –

ответ

0

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

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

На самом деле, IMO на вызов 'vswprintf' не должен влиять на локаль, но вызов' fputsw' должен завершиться неудачно ... –

+0

Вы действительно правы! Кстати, под Ubuntu 11.04 вызов не только преуспевает, но и вывод корректен даже без установки локали. – Xaxx

+0

@Xaxx - рад, что это помогло. Я думаю, Ubuntu 11.04 должен быть более разрешительным. Я попытался в Ubuntu 12.10, и он дал неправильные символы (на странице руководства указано, что должен быть установлен LC_CTYPE). – teppic