首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Visual字符集“Not”vs“多字节字符集”

Visual字符集“Not”vs“多字节字符集”
EN

Stack Overflow用户
提问于 2013-07-19 09:17:03
回答 2查看 16.1K关注 0票数 12

我使用了一个遗留应用程序,并试图在Multi byte character setNot 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

所以,就像工作研究一样。我的地区设置为日语

效应对硬编码字符串的影响

代码语言:javascript
复制
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中的编码字符串

因此,使用以下代码:

代码语言:javascript
复制
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打开文件

因此,使用以下代码:

代码语言:javascript
复制
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);

并选择:

  • C:\Temp\テスト\テopenw.txt
  • C:\Temp\テスト\テopenw.txt

产量:

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以使用WA之外,定义实际上并没有任何魔力。因此,我看不出Not SetMulti byte character set之间有什么区别。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-19 11:33:51

不,它的工作方式不是这样的。唯一发生的事情是宏被定义了,否则它不会对编译器产生神奇的影响。很少实际编写使用#ifdef _MBCS测试这个宏的代码。

您几乎总是把它留给助手函数来进行转换。与WideCharToMultiByte()、OLE2A()或wctombs()类似。这些转换函数总是考虑多字节编码,并以代码页为指导。_MBCS是一次历史事故,仅在几年前多字节编码还不常见的时候才与之相关。与使用非Unicode编码非常相似的是,现在也是一个历史工件。

票数 8
EN

Stack Overflow用户

发布于 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中的泛型文本映射。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17742379

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档