我正在使用遗留应用程序,而我正试图找出Multi byte character set
选项下使用Not Set
和Character Set
编译的应用程序之间的区别。
我理解使用Multi byte character set
进行编译定义了_MBCS
,允许使用多字节字符集代码页,并且使用Not set
不定义_MBCS
,其中只允许使用单字节字符集代码页。
在使用Not Set
的情况下,我假设我们只能使用此页面上的单字节字符集代码页:http://msdn.microsoft.com/en-gb/goglobal/bb964654.aspx
因此,我认为使用Not Set
是正确的,应用程序将无法编码和编写或读取远东语言,因为它们是在双字节字符集代码页中定义的(和当然是Unicode)?
接下来,如果定义了Multi byte character
set,单字节和多字节字符集代码页是可用的,还是只有多字节字符集代码页?我猜它必须支持欧洲语言。
谢谢,
安迪
进一步阅读
这些页面上的答案没有回答我的问题,但有助于我的理解: About the "Character set" option in visual studio 2010
研究
所以,就像工作研究一样......我的语言环境设置为日语
对硬编码字符串的影响
char *foo = "Jap text: テスト";
wchar_t *bar = L"Jap text: テスト";
使用Unicode
* foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (Code page 932)
* bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 or UCS-2
使用Multi byte character set
* foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (Code page 932)
* bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 or UCS-2
使用Not Set
* foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (Code page 932)
* bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 or UCS-2
结论: 字符编码对硬编码字符串没有任何影响。虽然如上定义字符似乎使用Locale定义的代码页,而wchar_t似乎使用UCS-2或UTF-16。
在W / A版本的Win32 API中使用编码字符串
所以,使用以下代码:
char *foo = "C:\\Temp\\テスト\\テa.txt";
wchar_t *bar = L"C:\\Temp\\テスト\\テw.txt";
CreateFileA(bar, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CreateFileW(foo, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
使用Unicode
结果:两个文件都已创建
使用Multi byte character set
结果:两个文件都已创建
使用Not set
结果:两个文件都已创建
结论:
无论选择哪个字符集,API的A
和W
版本都需要相同的编码。从这一点,也许我们可以假设所有Character Set
选项都在API的版本之间切换。因此,A
版本始终要求当前代码页和W
版本的编码中的字符串始终需要UTF-16或UCS-2。
使用W和A Win32 API打开文件
所以使用以下代码:
char filea[MAX_PATH] = {0};
OPENFILENAMEA ofna = {0};
ofna.lStructSize = sizeof ( ofna );
ofna.hwndOwner = NULL ;
ofna.lpstrFile = filea ;
ofna.nMaxFile = MAX_PATH;
ofna.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofna.nFilterIndex =1;
ofna.lpstrFileTitle = NULL ;
ofna.nMaxFileTitle = 0 ;
ofna.lpstrInitialDir=NULL ;
ofna.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
wchar_t filew[MAX_PATH] = {0};
OPENFILENAMEW ofnw = {0};
ofnw.lStructSize = sizeof ( ofnw );
ofnw.hwndOwner = NULL ;
ofnw.lpstrFile = filew ;
ofnw.nMaxFile = MAX_PATH;
ofnw.lpstrFilter = L"All\0*.*\0Text\0*.TXT\0";
ofnw.nFilterIndex =1;
ofnw.lpstrFileTitle = NULL;
ofnw.nMaxFileTitle = 0 ;
ofnw.lpstrInitialDir=NULL ;
ofnw.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
GetOpenFileNameA(&ofna);
GetOpenFileNameW(&ofnw);
并选择:
收率:
使用Unicode
* filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (Code page 932)
* filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 or UCS-2
使用Multi byte character set
* filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (Code page 932)
* filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 or UCS-2
使用Not Set
* filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (Code page 932)
* filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 or UCS-2
结论:
同样,Character Set
设置与Win32 API的行为无关。 A
版本似乎总是返回带有活动代码页编码的字符串,而W
版本总是返回UTF-16或UCS-2。我实际上可以在这个很好的答案中看到这个解释:https://stackoverflow.com/a/3299860/187100。
Ultimate Conculsion
汉斯似乎是正确的,他说除了改变Win32 API以使用W
或A
之外,定义对它没有任何魔力。因此,我无法真正看到Not Set
和Multi byte character set
之间存在任何差异。
答案 0 :(得分:7)
不,这不是它的工作方式。唯一发生的事情是宏被定义,否则它对编译器没有神奇的影响。实际编写使用#ifdef _MBCS
来测试此宏的代码是非常。
你几乎总是把它留给辅助功能来进行转换。像WideCharToMultiByte(),OLE2A()或wctombs()。在代码页的指导下,哪些是始终考虑多字节编码的转换函数。 _MBCS是一个历史性的事故,仅在25年多以前相关,当时多字节编码还不常见。就像使用非Unicode编码一样,现在也是一种历史文物。
答案 1 :(得分:0)
在reference中声明:
根据定义,ASCII字符集是所有字符集的子集 多字节字符集。在许多多字节字符集中,每个 0x00 - 0x7F范围内的字符与该字符相同 在ASCII字符集中具有相同的值。例如,在两者中 ASCII和MBCS字符串,1字节的NULL字符('\ 0')具有 值0x00并表示终止空字符。
正如您所猜测的那样,启用_MBCS
Visual Studio也支持ASCII
单个字符集。
在第二个reference中,即使我们启用_MBCS
,也似乎支持单个字符集:
MBCS / Unicode可移植性:使用Tchar.h头文件,您可以构建 来自相同源的单字节,MBCS和Unicode应用程序。 Tchar.h定义了以_tcs为前缀的宏,它映射到str,_mbs或 wcs功能,视情况而定。要构建MBCS,请定义符号_MBCS。 要构建Unicode,请定义符号_UNICODE。默认情况下,_MBCS是 为MFC应用程序定义。有关更多信息,请参阅Generic-Text Tchar.h中的映射。