#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
char* str = "I 服了 You";
printf("%s\n", str);
return 0;
}
操作系统是如何处理这种字符串的?能否讲一讲底层的处理过程?
32 个解决方案
#1
中文也被转为字符了啊。
你可以调试下下
你可以调试下下
#2
2个字符
#3
中文占两个字符,而且每个字符的符号位都是1,asc码的符号位都是0
#4
这要看底层字符集映射了,比如TC2.0不支持显示中文字符而只有ASCII码的映射。
#5
chcp命令了解一下吧
#6
一个中文占16位
#7
有什么依据吗?谢谢!
#8
仁兄,基本常识,嘿嘿
GB2312-80
GB2312码是*国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》,由国家标准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。将GB码两个字节的最高位置1以示区别ASCII。
#9
#include <iostream>
using namespace std;
int main()
{
char* str = "I ·þÁË You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
中文对应两个字节,且都是负的,说明首位为1
#10
上面字符串是 "I 服了 You"
#11
int main()
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
可以通过这个结果来验证GB2312
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。将GB码两个字节的最高位置1以示区别ASCII。
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
可以通过这个结果来验证GB2312
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。将GB码两个字节的最高位置1以示区别ASCII。
#12
0x670D, /* GB2312 Code: 0xB7FE ==>服 Row:23 Col:94 */
服这个字的GB2312编码找到了。
服这个字的GB2312编码找到了。
#13
但是我想知道0x670D 跟
-73
-2
是如何转换的?求高手分析分析!
-73
-2
是如何转换的?求高手分析分析!
#14
0X670D应该是Unicode编码,用WideCharToMultiByte可以转换。Unicode编码要使用wchar_t类型的。
#15
这个嘛,最好看看计算机组成原理和GB2312的标准,想想当初,我硬是把那个字符集文档打印了。上面每个字符,包括汉字的编码都是有的。
对于简体字:两个字节的最高位置1
对于繁体字:两个字节的最字节最高位置1,低字节最高位置0(此字节与ASCII有重叠).
通常在串匹配中,对于汉字首先判断其高字节最高位,若是1,则可肯定是汉字(当然对于中文字符也有个连续的编码范围)。然后判断低字节的最高位才能判断是不是繁体。
#16
ansi的字符中中文是gb2312编码,占两个字节,英文是1个字节。如果第一个字节大于0x80,则和后面的是连在一起的。
#17
Unicode和GB2312只能根据转换表一一对应转换。
比如“服”的Unicode是0x670D,GB2312是0xB7FE
#18
//GBK汉字内码范围
//区码 ,位码
//81-A0 ,40-7E 80-FE
//AA-AF ,40-7E 80-A0
//B0-D6 ,40-7E 80-FE
//D7 ,40-7E 80-F9
//D8-F7 ,40-7E 80-FE
//F8-FE ,40-7E 80-A0
//区码 ,位码
//81-A0 ,40-7E 80-FE
//AA-AF ,40-7E 80-A0
//B0-D6 ,40-7E 80-FE
//D7 ,40-7E 80-F9
//D8-F7 ,40-7E 80-FE
//F8-FE ,40-7E 80-A0
#19
我的意思是这里的-73和-2是则么来的?如何得出的呢?
#20
那麻烦你给试试,看这个-73和-2是如何得到的》
#21
就是想对此问题有个清晰的认识,为什么“服”,输出的就是-73和-2!就这么明确!
#22
楼主贴出来的代码中,是用char来存储字符串的,所以是ANSI的字符规则,中文是GBK的编码,每个中文字符占用2个字节,且每个字节的最高位为1。所以可以用这种方法来判断中英文混排时哪些是中文字符。而上面讨论的汉字“服”对应的-73(0xBF)和-2(0xFE)这两个字节,只要查一下GBK的编码库BFFE对应的汉字是哪个,就一目了然了。(附上GBK汉字编码集链接http://baike.baidu.com/view/25421.htm?fr=ala0_1_1)
关于Unicode和ANSI的转换,因为Unicode是在后面出来了,为了统一全球不同语言的ANSI字符集而产生的,所以对这些字符集做了重新编码。各个语言对应的unicode编码范围可以参看http://baike.baidu.com/view/40801.htm?fr=ala0_1中相关部分。
ANSI字符要转成Unicode字符,需要知道该字符编码对应Unicode字符编码的偏移量,这样的偏移量列表在一些专门做字符转换的论坛可能能拿到。不过在windows上通过MultiByteToWideChar和WideCharToMultiByte上可以做这两者的转换。
关于Unicode和ANSI的转换,因为Unicode是在后面出来了,为了统一全球不同语言的ANSI字符集而产生的,所以对这些字符集做了重新编码。各个语言对应的unicode编码范围可以参看http://baike.baidu.com/view/40801.htm?fr=ala0_1中相关部分。
ANSI字符要转成Unicode字符,需要知道该字符编码对应Unicode字符编码的偏移量,这样的偏移量列表在一些专门做字符转换的论坛可能能拿到。不过在windows上通过MultiByteToWideChar和WideCharToMultiByte上可以做这两者的转换。
#23
我查了GBK的编码,GBK的编码库BFFE对应的汉字是服字!
但是我还有很多困惑,比如程序运行的时候,把“服”字如何放到内存中的?先转换成UNICODE字符码?
然后再分两个字节放到内存?最后 “服”对应的-73(不是0xBF,0XBF对应的是-65)和-2(0xFE)这两个字节,请问这里为什么是-73呢?
#24
Sorry,算错了,“服”字对应的-73(0xB7)和-2(0xFE).
B7 0 1 2 3 4 5 6 7 8 9 A B C D E F
A 贰 发 罚 筏 伐 乏 阀 法 珐 藩 帆 番 翻 樊 矾
B 钒 繁 凡 烦 反 返 范 贩 犯 饭 泛 坊 芳 方 肪 房
C 防 妨 仿 访 纺 放 菲 非 啡 飞 肥 匪 诽 吠 肺 废
D 沸 费 芬 酚 吩 氛 分 纷 坟 焚 汾 粉 奋 份 忿 愤
E 粪 丰 封 枫 蜂 峰 锋 风 疯 烽 逢 冯 缝 讽 奉 凤
F 佛 否 夫 敷 肤 孵 扶 拂 辐 幅 氟 符 伏 俘 服
#25
谢谢!那系统是如何把“服”字放到内存中的?先转换成UNICODE字符码?GBK?
然后再分两个字节放到内存?然后如何取出来的呢?
#26
你当前使用的系统是简体中文系统。代码页也是gbk之类,
你放到其他语言的操作系统应该就不能正确输出了。
你放到其他语言的操作系统应该就不能正确输出了。
#27
中文16位2个字节表示一个字符,而且unicode的编码也很复杂,所以出现73 32 -73 -2 -63 -53 32 89 111 117,32是空格,正数应该是英文字母,负数估计要两个一起看才能表示一个中文字,也有可能用负数段表示中文
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
你自己就可以算得出来了。FE就对应-2,B7就对应-73
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
你自己就可以算得出来了。FE就对应-2,B7就对应-73
#28
收工!
#29
系统不会做转换,需要程序转换,在程序里,用wchar_t声明字符串数组可以保存unicode字符,用char声明的字符串数组可以保存ANSI字符,这个就是为什么有些程序在编写时用char字符串数组保存界面显示的文本内容,在不支持对应字符集的OS上会显示乱码,而如果是用wchar_t字符串数组保存,就不会有这个问题的原因。
#30
安安你好强大!
#31
你可以将英文也转换为宽字符就OK了,我前些天天天都在琢磨这些
CString CCodeToLight::DBCTOSBC(CString strInput)
{
char *pSzTemp = new char[strInput.GetLength() + 1];
CString strResult;
BYTE c1, c2;
pSzTemp = (LPSTR)(LPCTSTR)strInput;
for (int i = 0; i < strInput.GetLength(); i++)
{
c1 = pSzTemp[i];
c2 = pSzTemp[i + 1];
if (163 <= c1)
{
strResult = strResult + char(c1);
strResult = strResult + char(c2);
i++;
}
else if (' ' == c1)
{
strResult = strResult + char(161);
strResult = strResult + char(161);
}
else if (163 > c1)
{
strResult = strResult + char(163);
strResult = strResult + char(c1 + 128);
}
}
return strResult;
}
#32
int main()
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
可以算得出来FE就对应-2,B7就对应-73
汉字对应2个字节,输出时先输出低地址。空格也对应一个ACSII码
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
可以算得出来FE就对应-2,B7就对应-73
汉字对应2个字节,输出时先输出低地址。空格也对应一个ACSII码
#1
中文也被转为字符了啊。
你可以调试下下
你可以调试下下
#2
2个字符
#3
中文占两个字符,而且每个字符的符号位都是1,asc码的符号位都是0
#4
这要看底层字符集映射了,比如TC2.0不支持显示中文字符而只有ASCII码的映射。
#5
chcp命令了解一下吧
#6
一个中文占16位
#7
有什么依据吗?谢谢!
#8
仁兄,基本常识,嘿嘿
GB2312-80
GB2312码是*国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》,由国家标准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。将GB码两个字节的最高位置1以示区别ASCII。
#9
#include <iostream>
using namespace std;
int main()
{
char* str = "I ·þÁË You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
中文对应两个字节,且都是负的,说明首位为1
#10
上面字符串是 "I 服了 You"
#11
int main()
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
可以通过这个结果来验证GB2312
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。将GB码两个字节的最高位置1以示区别ASCII。
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
可以通过这个结果来验证GB2312
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,第二个字节为“低字节”。将GB码两个字节的最高位置1以示区别ASCII。
#12
0x670D, /* GB2312 Code: 0xB7FE ==>服 Row:23 Col:94 */
服这个字的GB2312编码找到了。
服这个字的GB2312编码找到了。
#13
但是我想知道0x670D 跟
-73
-2
是如何转换的?求高手分析分析!
-73
-2
是如何转换的?求高手分析分析!
#14
0X670D应该是Unicode编码,用WideCharToMultiByte可以转换。Unicode编码要使用wchar_t类型的。
#15
这个嘛,最好看看计算机组成原理和GB2312的标准,想想当初,我硬是把那个字符集文档打印了。上面每个字符,包括汉字的编码都是有的。
对于简体字:两个字节的最高位置1
对于繁体字:两个字节的最字节最高位置1,低字节最高位置0(此字节与ASCII有重叠).
通常在串匹配中,对于汉字首先判断其高字节最高位,若是1,则可肯定是汉字(当然对于中文字符也有个连续的编码范围)。然后判断低字节的最高位才能判断是不是繁体。
#16
ansi的字符中中文是gb2312编码,占两个字节,英文是1个字节。如果第一个字节大于0x80,则和后面的是连在一起的。
#17
Unicode和GB2312只能根据转换表一一对应转换。
比如“服”的Unicode是0x670D,GB2312是0xB7FE
#18
//GBK汉字内码范围
//区码 ,位码
//81-A0 ,40-7E 80-FE
//AA-AF ,40-7E 80-A0
//B0-D6 ,40-7E 80-FE
//D7 ,40-7E 80-F9
//D8-F7 ,40-7E 80-FE
//F8-FE ,40-7E 80-A0
//区码 ,位码
//81-A0 ,40-7E 80-FE
//AA-AF ,40-7E 80-A0
//B0-D6 ,40-7E 80-FE
//D7 ,40-7E 80-F9
//D8-F7 ,40-7E 80-FE
//F8-FE ,40-7E 80-A0
#19
我的意思是这里的-73和-2是则么来的?如何得出的呢?
#20
那麻烦你给试试,看这个-73和-2是如何得到的》
#21
就是想对此问题有个清晰的认识,为什么“服”,输出的就是-73和-2!就这么明确!
#22
楼主贴出来的代码中,是用char来存储字符串的,所以是ANSI的字符规则,中文是GBK的编码,每个中文字符占用2个字节,且每个字节的最高位为1。所以可以用这种方法来判断中英文混排时哪些是中文字符。而上面讨论的汉字“服”对应的-73(0xBF)和-2(0xFE)这两个字节,只要查一下GBK的编码库BFFE对应的汉字是哪个,就一目了然了。(附上GBK汉字编码集链接http://baike.baidu.com/view/25421.htm?fr=ala0_1_1)
关于Unicode和ANSI的转换,因为Unicode是在后面出来了,为了统一全球不同语言的ANSI字符集而产生的,所以对这些字符集做了重新编码。各个语言对应的unicode编码范围可以参看http://baike.baidu.com/view/40801.htm?fr=ala0_1中相关部分。
ANSI字符要转成Unicode字符,需要知道该字符编码对应Unicode字符编码的偏移量,这样的偏移量列表在一些专门做字符转换的论坛可能能拿到。不过在windows上通过MultiByteToWideChar和WideCharToMultiByte上可以做这两者的转换。
关于Unicode和ANSI的转换,因为Unicode是在后面出来了,为了统一全球不同语言的ANSI字符集而产生的,所以对这些字符集做了重新编码。各个语言对应的unicode编码范围可以参看http://baike.baidu.com/view/40801.htm?fr=ala0_1中相关部分。
ANSI字符要转成Unicode字符,需要知道该字符编码对应Unicode字符编码的偏移量,这样的偏移量列表在一些专门做字符转换的论坛可能能拿到。不过在windows上通过MultiByteToWideChar和WideCharToMultiByte上可以做这两者的转换。
#23
我查了GBK的编码,GBK的编码库BFFE对应的汉字是服字!
但是我还有很多困惑,比如程序运行的时候,把“服”字如何放到内存中的?先转换成UNICODE字符码?
然后再分两个字节放到内存?最后 “服”对应的-73(不是0xBF,0XBF对应的是-65)和-2(0xFE)这两个字节,请问这里为什么是-73呢?
#24
Sorry,算错了,“服”字对应的-73(0xB7)和-2(0xFE).
B7 0 1 2 3 4 5 6 7 8 9 A B C D E F
A 贰 发 罚 筏 伐 乏 阀 法 珐 藩 帆 番 翻 樊 矾
B 钒 繁 凡 烦 反 返 范 贩 犯 饭 泛 坊 芳 方 肪 房
C 防 妨 仿 访 纺 放 菲 非 啡 飞 肥 匪 诽 吠 肺 废
D 沸 费 芬 酚 吩 氛 分 纷 坟 焚 汾 粉 奋 份 忿 愤
E 粪 丰 封 枫 蜂 峰 锋 风 疯 烽 逢 冯 缝 讽 奉 凤
F 佛 否 夫 敷 肤 孵 扶 拂 辐 幅 氟 符 伏 俘 服
#25
谢谢!那系统是如何把“服”字放到内存中的?先转换成UNICODE字符码?GBK?
然后再分两个字节放到内存?然后如何取出来的呢?
#26
你当前使用的系统是简体中文系统。代码页也是gbk之类,
你放到其他语言的操作系统应该就不能正确输出了。
你放到其他语言的操作系统应该就不能正确输出了。
#27
中文16位2个字节表示一个字符,而且unicode的编码也很复杂,所以出现73 32 -73 -2 -63 -53 32 89 111 117,32是空格,正数应该是英文字母,负数估计要两个一起看才能表示一个中文字,也有可能用负数段表示中文
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
你自己就可以算得出来了。FE就对应-2,B7就对应-73
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
你自己就可以算得出来了。FE就对应-2,B7就对应-73
#28
收工!
#29
系统不会做转换,需要程序转换,在程序里,用wchar_t声明字符串数组可以保存unicode字符,用char声明的字符串数组可以保存ANSI字符,这个就是为什么有些程序在编写时用char字符串数组保存界面显示的文本内容,在不支持对应字符集的OS上会显示乱码,而如果是用wchar_t字符串数组保存,就不会有这个问题的原因。
#30
安安你好强大!
#31
你可以将英文也转换为宽字符就OK了,我前些天天天都在琢磨这些
CString CCodeToLight::DBCTOSBC(CString strInput)
{
char *pSzTemp = new char[strInput.GetLength() + 1];
CString strResult;
BYTE c1, c2;
pSzTemp = (LPSTR)(LPCTSTR)strInput;
for (int i = 0; i < strInput.GetLength(); i++)
{
c1 = pSzTemp[i];
c2 = pSzTemp[i + 1];
if (163 <= c1)
{
strResult = strResult + char(c1);
strResult = strResult + char(c2);
i++;
}
else if (' ' == c1)
{
strResult = strResult + char(161);
strResult = strResult + char(161);
}
else if (163 > c1)
{
strResult = strResult + char(163);
strResult = strResult + char(c1 + 128);
}
}
return strResult;
}
#32
int main()
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
可以算得出来FE就对应-2,B7就对应-73
汉字对应2个字节,输出时先输出低地址。空格也对应一个ACSII码
{
char* str = "I 服了 You";
printf("%s\n", str);
for(int i=0; i<strlen(str); i++)
printf("%d\n",str[i]);
system("PAUSE");
return EXIT_SUCCESS;
}
结果为:
73
32
-73
-2
-63
-53
32
89
111
117
1.GBK编码的服是 0xB7FE
2.B7FE在内存里的表示是
高地址 FE B7 低地址。
可以算得出来FE就对应-2,B7就对应-73
汉字对应2个字节,输出时先输出低地址。空格也对应一个ACSII码