swprintf не работает с символами юникода в xcode, но работает в visual studio - PullRequest
1 голос
/ 03 февраля 2011

При попытке конвертировать существующий код для поддержки символов Юникода эта проблема всплыла. Если я попытаюсь передать символ Unicode (в данном случае я использую символ евро) в любую из функций * wprintf, это не удастся, но, по-видимому, только в xcode. Тот же код отлично работает в visual studio, и я даже смог найти друга, который успешно протестировал его с gcc на linux. Вот код нарушения:

wchar_t _teststring[10] = L"";
int _iRetVal = swprintf(_teststring, 10, L"A¥€");

wprintf(L"return: %d\n", _iRetVal);

// print values stored in string to check if anything got corrupted
for (int i=0; i<wcslen(_teststring); ++i) {
    wprintf(L"%d: (%d)\n", i, _teststring[i]);
}

В xcode вызов swprintf вернет -1, в то время как в visual studio он завершится успешно и продолжит выводить правильные значения для каждого из 3 символов (65, 165, 8364).

Я гугле долго и упорно решений, одно из предложений, которое появилось несколько раз используют вызов таких как:

setlocale(LC_CTYPE, "UTF-8");

Я пробовал различные комбинации аргументов с этой функцией, но безуспешно, при дальнейшем исследовании она возвращает нулевое значение, если я пытаюсь установить для локали любое значение, отличное от значения по умолчанию "C".

Я в недоумении относительно того, что еще я могу попытаться решить эту проблему, и тот факт, что он работает в других компиляторах / платформах, только делает его еще более неприятным. Любая помощь будет высоко ценится!

EDIT: Просто подумал, что я хотел бы добавить, что при сбое вызова swprintf устанавливается код ошибки (92), который определяется как:

#define EILSEQ      92      /* Illegal byte sequence */

Ответы [ 3 ]

1 голос
/ 22 ноября 2011

Если вы используете Xcode 4+, убедитесь, что вы установили соответствующую кодировку для ваших файлов, которые содержат ваши строки. Вы можете найти настройки кодирования на правой панели в группе «Настройки текста».

1 голос
/ 07 ноября 2016

Microsoft планировала совместимость с другими компиляторами, начиная с VS 2015, но, наконец, этого не произошло из-за проблем с унаследованным кодом, см. ссылка .

К счастью, вы все еще можете включить стандарт ISO C (C99) в VS 2015, добавив макрос препроцессора _CRT_STDIO_ISO_WIDE_SPECIFIERS. Рекомендуется при написании переносимого кода.

1 голос
/ 03 февраля 2011

Должно работать, если вы выбираете локаль из окружения:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(void) {
  setlocale(LC_ALL, "");
wchar_t _teststring[10] = L"";
int _iRetVal = swprintf(_teststring, 10, L"A¥€");

wprintf(L"return: %d\n", _iRetVal);

// print values stored in string to check if anything got corrupted
for (int i=0; i<wcslen(_teststring); ++i) {
    wprintf(L"%d: (%d)\n", i, _teststring[i]);
}

}

В моей OS X 10.6 это работает, как и ожидалось, с GCC 4.2.1, но при компиляции с CLang 1.6 он помещает байты UTF-8 в строку результата.

Я также мог бы скомпилировать это с помощью Xcode (используя стандартный шаблон консольного приложения C ++), но поскольку графические приложения в OS X не имеют требуемых переменных среды локали, он не работает в консоли Xcode. С другой стороны, это всегда работает в приложении Terminal.

Вы также можете установить локаль на en_US.UTF-8 (setlocale(LC_ALL, "en_US.UTF-8")), но это непереносимо. В зависимости от вашей цели, могут быть лучшие альтернативы wsprintf.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...