swprintf在xcode中使用unicode字符失败,但在visual studio中工作

时间:2011-02-03 10:39:51

标签: c++ c xcode gcc unicode

在尝试转换某些现有代码以支持unicode字符时,会弹出此问题。如果我尝试将unicode字符(在本例中使用欧元符号)传递到任何* wprintf函数中,它将失败,但似乎只在xcode中。相同的代码在visual studio中运行良好,我甚至可以让朋友在linux上使用gcc成功测试它。这是违规代码:

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”以外的任何值,则它似乎返回null。

我不知道还有什么可以尝试解决这个问题,而且它在其他编译器/平台上工作的事实让它更令人沮丧。任何帮助将不胜感激!

编辑: 刚想我会补充一点,当swprintf调用失败时,它会设置一个错误代码(92),定义为:

#define EILSEQ      92      /* Illegal byte sequence */

4 个答案:

答案 0 :(得分:1)

如果从环境中获取语言环境,它应该可以工作:

#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的控制台中不起作用。另一方面,它总是在终端应用程序中工作。

您还可以将区域设置设置为en_US.UTF-8setlocale(LC_ALL, "en_US.UTF-8")),但这是不可移植的。根据您的目标,wsprintf可能有更好的替代方案。

答案 1 :(得分:1)

如果您使用的是Xcode 4+,请确保为包含字符串的文件设置了适当的编码。您可以在“文本设置”组下的右窗格中找到编码设置。

答案 2 :(得分:1)

Microsoft计划从VS 2015开始与其他编译器兼容,但最终由于遗留代码问题而从未发生过,请参阅link

幸运的是,您仍然可以通过添加_CRT_STDIO_ISO_WIDE_SPECIFIERS预处理器宏来在VS 2015中启用ISO C(C99)标准。建议在编写可移植代码时使用。

答案 3 :(得分:0)

我发现在格式化字符串中使用“%S”(大写)是可行的。

“%s”用于8位字符,“%S”用于16位或32位字符。

请参阅:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html

我正在使用使用Clang 10的Qt Creator 4.11。