2013-03-15 96 views
2

我使用GCC和Mac OS X从vswprintf中得到莫名其妙的失败(返回值为-1)(在Mac OS X 10.6和10.8下使用gcc 4.0和4.2.1测试)GCC在Linux下是不是受影响.Visual Studio也是不是受影响)。vswprintf在Mac OS X下某些unicode codepoints失败

为了证明我有最低限度从here适配,使得它打印出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字符的任意字符串将触发此问题。任何人都可以阐明为什么会发生这种情况?这似乎是一个太大的问题,以前没有注意到!

+0

请问您的源文件的编码匹配有望在字符串编码? – Dmitri 2013-03-15 18:03:31

+0

我希望'fputws'调用在缺省''C“'语言环境中对超出范围字符失败,但'vswprintf'应该可以工作。 – 2013-03-15 23:41:48

+0

标题中没有“GCC vswprintf”。在Mac OS X上,GCC在GNU/Linux上的表现与GCC有所不同,原因是'vswprintf'与GCC无关,它是由操作系统的C库'libc'提供的 – 2013-03-17 17:50:50

回答

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'调用不应该受locale影响,但'fputsw'调用应该会失败... – 2013-03-15 23:42:47

+0

你确实是对的!顺便说一句,在Ubuntu 11.04下,调用不仅成功,而且即使没有设置语言环境,输出也是正确的。 – Xaxx 2013-03-21 12:55:58

+0

@Xaxx - 很高兴帮助。我认为Ubuntu 11.04必须更加宽容。我在Ubuntu 12.10中尝试过,它给了错误的字符(手册页说LC_CTYPE必须设置)。 – teppic 2013-03-21 12:57:37