我使用了一个遗留应用程序,并试图在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集,那么单字节字符集代码页和多字节字符集代码页都可用,还是只有多字节字符集代码页?我猜这两种语言都要支持欧洲语言。
谢谢,
安迪
再读
这些页面上的答案没有回答我的问题,但对我的理解有所帮助:关于visual studio 2010中的“字符集”选项
Research
所以,就像工作研究一样。我的地区设置为日语
效应对硬编码字符串的影响
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 (代码第932页) *酒吧= 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或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 (代码第932页) *酒吧= 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或UCS-2
用Not Set编译
*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (代码第932页) *酒吧= 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或UCS-2
结论:字符编码对硬编码字符串没有任何影响。尽管如上所述,定义字符似乎使用了地区定义的代码页,而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 5c 54 65 6d 70 5c 83 83 83 58 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (代码第932页) *文件= 43 00 3a 00 5 c 00 54 00 00 6 d 00 70 00 00 5 c 00 c6 30 b9 30 c8 30 c 00 c6 30 6 f 00 70 00 00 00 77 00 2 e 00 74 00 78 0074 == UTF-16或UCS-2
用Multi byte character set编译时
*filea = 43 3a 5c 5c 54 65 6d 70 5c 83 83 83 58 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (代码第932页) *文件= 43 00 3a 00 5 c 00 54 00 00 6 d 00 70 00 00 5 c 00 c6 30 b9 30 c8 30 c 00 c6 30 6 f 00 70 00 00 00 77 00 2 e 00 74 00 78 0074 == UTF-16或UCS-2
用Not Set编译时
*filea = 43 3a 5c 5c 54 65 6d 70 5c 83 83 83 58 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (代码第932页) *文件= 43 00 3a 00 5 c 00 54 00 00 6 d 00 70 00 00 5 c 00 c6 30 b9 30 c8 30 c 00 c6 30 6 f 00 70 00 00 00 77 00 2 e 00 74 00 78 0074 == UTF-16或UCS-2
结论:同样,Character Set设置对Win32 API的行为没有影响。A版本似乎总是返回带有活动代码页编码的字符串,而W版本总是返回UTF-16或UCS-2。实际上,我可以在这个很好的答案中看到这一点:https://stackoverflow.com/a/3299860/187100。
极限计算
汉斯似乎是正确的,他说,除了改变Win32 API以使用W或A之外,定义实际上并没有任何魔力。因此,我看不出Not Set和Multi byte character set之间有什么区别。
发布于 2013-07-19 11:33:51
不,它的工作方式不是这样的。唯一发生的事情是宏被定义了,否则它不会对编译器产生神奇的影响。很少实际编写使用#ifdef _MBCS测试这个宏的代码。
您几乎总是把它留给助手函数来进行转换。与WideCharToMultiByte()、OLE2A()或wctombs()类似。这些转换函数总是考虑多字节编码,并以代码页为指导。_MBCS是一次历史事故,仅在几年前多字节编码还不常见的时候才与之相关。与使用非Unicode编码非常相似的是,现在也是一个历史工件。
发布于 2013-07-19 10:00:42
在参考文献中指出:
根据定义,ASCII字符集是所有多字节字符集的子集.在许多多字节字符集中,0x00-0x7F范围内的每个字符都与ASCII字符集中具有相同值的字符相同。例如,在ASCII和MBCS字符串中,1字节空字符('\0')的值为0x00,并指示终止空字符。
正如您所猜测的那样,通过启用_MBCS,Visual还支持ASCII单字符集。
在第二个参考文献中,即使启用了_MBCS,似乎也支持单个字符集。
MBCS /Unicode可移植性:使用Tchar.h头文件,可以从相同的来源构建单字节、MBCS和Unicode应用程序。H定义以_tcs为前缀的宏,这些宏可以映射到str、_mbs或wcs函数。若要构建MBCS,请定义符号_MBCS。若要生成Unicode,请定义符号_UNICODE。默认情况下,_MBCS是为MFC应用程序定义的。有关更多信息,请参见Tchar.h中的泛型文本映射。
https://stackoverflow.com/questions/17742379
复制相似问题