utf-8编码输出问题

freeskyo 2011-10-19 06:06:47

int z =0;
for(z=0;z<strlen(sresult);z++)
{
printf("%c -- 0x%02x\n", sresult[z],sresult[z]);
}


sresult里面的内容是:<Message>请求成功</Message>
输出是:
< -- 0x3c
M -- 0x4d
e -- 0x65
s -- 0x73
s -- 0x73
a -- 0x61
g -- 0x67
e -- 0x65
> -- 0x3e
枭- 0xffffffe8
¯ -- 0xffffffaf
· -- 0xffffffb7
䞭- 0xffffffe6
± -- 0xffffffb1
‚ -- 0xffffff82
䞭- 0xffffffe6
ˆ -- 0xffffff88
 -- 0xffffff90
㞭- 0xffffffe5
Š -- 0xffffff8a
Ÿ -- 0xffffff9f
< -- 0x3c
/ -- 0x2f
M -- 0x4d
e -- 0x65
s -- 0x73
s -- 0x73
a -- 0x61
g -- 0x67
e -- 0x65
> -- 0x3e

结果输出汉字来说,应该是1个汉字占了3个字节;
1) 但定宽0x%02x 输出汉字时前面加了很多f为什么;
2) utf-8 如何编码的,请帮忙举“请”字的示例,当然也可以和标准ASII码及Unicode编码结果做一个比较,列一个表出来;
3) 如何用c找出上面一段输入中utf-8编码是汉字字符(可以写写code,也可以说说思路)

谢谢
...全文
179 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
辰岡墨竹 2011-10-20
  • 打赏
  • 举报
回复
现在的Linux内核,就是用的UTF-8,所以你在Linux下处理UTF-8是很容易的,不需要特别转换。
luciferisnotsatan 2011-10-20
  • 打赏
  • 举报
回复
http://zh.wikipedia.org/wiki/UTF-8
http://zh.wikipedia.org/wiki/UCS-4

赵4老师 2011-10-20
  • 打赏
  • 举报
回复
更正上帖最后两行
//    6    C    4    9
// 0110 1100 0100 1001
// wwww xxxx yyyy zzzz
// wwww xxxxyy yyzzzz
// 1110wwww 10xxxxyy 10yyzzzz。
// 11100110 10110001 10001001
// E 6 B 1 8 9
//“汉”字的UTF-8编码是E6 B1 89

chos2006 2011-10-20
  • 打赏
  • 举报
回复
学习一下
赵4老师 2011-10-20
  • 打赏
  • 举报
回复
// UTF-8 编码字符理论上可以最多到 6个字节长,但目前全世界的所
// 有文字和符号种类加起来也只要编到 4个字节长就够了。
//   UTF-8 是以 8位(即 1个字节)为单元对原始码进行编码(注意一
// 点:这里所讲的原始码都是指Unicode码),并规定:多字节码(2个字
// 节以上才称为多字节)以转换后第1个字节起头的连续“1”的数目(这
// 些连续“1”称为标记位),表示转换成几个字节:“110”连续两个
// “1”,表示转换结果为2个字节,“1110”表示3个字节,而“11110”
// 则表示4个字节……跟随在标记位之后的“0”,其作用是分隔标记位和
// 字符码位。第2~第4个字节的起头两个位固定设置为“10”,也作为标
// 记,剩下的6个位才做为字符码位使用。
//   这样,2字节UTF-8码剩下11个字符码位,可用以转换0080~07FF的
// 原始字符码,3字节剩下16个字符码位,可用以转换0800~FFFF的原始字
// 符码,由此类推。编码方式的模板如下:
//
// 原始码(16进制) UTF-8编码(二进制)
// --------------------------------------------
// 0000 - 007F 0xxxxxxx
// 0080 - 07FF 110xxxxx 10xxxxxx
// 0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
// ……
// --------------------------------------------
//
//   模板中的“x”表示字符码。
//   Ascii码<007F,编为1个
// 字节的UTF-8码。汉字的 Unicode编码范围为0800-FFFF,所以被编为
// 3个字节的UTF-8码。
//   例如“汉”字的Unicode编码是6C49,6C49在0800-FFFF之间,所以
// 要用3个字节的模板:1110wwww 10xxxxyy 10yyzzzz。

// 6 C 4 9
// 0110 1100 0100 1001
// wwww xxxx yyyy zzzz
// wwww xxxxyy yyzzzz
// 1110wwww 10xxxxyy 10yyzzzz。
// 11100110 10110001 10001001
// E 6 B 1 4 9
//“汉”字的UTF-8编码是E6 B1 49
freeskyo 2011-10-20
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 sparkcoollee 的回复:]

char *str = "abcdef";
int size = strlen(str);
for (int i =0;i<size;)
{
if ((unsigned)str[i]<0x7f)
{
i++;//英文
}
else if ((unsigned)str[i]<0xe0)
{
i += 2;
}
else if ((unsigned)str[i]<0xf0)……
[/Quote]

谢谢!

大家继续吧!
sparkcoollee 2011-10-19
  • 打赏
  • 举报
回复
char *str = "abcdef";
int size = strlen(str);
for (int i =0;i<size;)
{
if ((unsigned)str[i]<0x7f)
{
i++;//英文
}
else if ((unsigned)str[i]<0xe0)
{
i += 2;
}
else if ((unsigned)str[i]<0xf0)
{
i += 3;//中文
}
else
{
throw("Error!!!\n");
}
}
//对于ffff的问题正如上面所述,当字符位负值时,会被强转成32个字节,负数采用补码形式。16进制输出形式是从左第一个非0位开始的,所以会出现英文字符正常输出,中文字符前面会有很多的fffff
freeskyo 2011-10-19
  • 打赏
  • 举报
回复
再继续吧,大家!给多一些信息
freeskyo 2011-10-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 akirya 的回复:]

类型提升呀
printf("%c -- 0x%02x\n", (unsigned char)sresult[z],(unsigned char)sresult[z]);
[/Quote]

牛, 就是老外写得细!~ 哈哈,好好看看
freeskyo 2011-10-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 bokutake 的回复:]

UTF-8是Unicode吗的,一种。所以如果要将ANSI字符转换为UTF-8的话,应该先转Unicode,然后有一对一的编码关系映射为UTF-8。
不过Windows提供了MultiByteToWideChar和WideCharToMultiByte。先用前者把ANSI转换为UTF-16L(Windows内部用的宽字节编码),再用后者指定CP_UTF8来把UTF-16L对应转换为UTF-8
……
[/Quote]

我的是linux 下
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 freeskyo 的回复:]

引用 1 楼 akirya 的回复:
1 char 是-128 127 ,当某个字节最高位是1 的时候 符号扩展了
2 utf-8是unicode的一种, google utf-8 编码规则
3 只能判断出来非ascii的部分。根据最高位


具体一点呀,网上n多版本,我都搞不清楚呀,还有上面我分析的那汉字转换的编码对吗,为什么"请字是"
枭- 0xffffffe8
¯ -- 0……
[/Quote]
那就看权威的rfc文档
http://tools.ietf.org/html/rfc3629
辰岡墨竹 2011-10-19
  • 打赏
  • 举报
回复
UTF-8是Unicode吗的,一种。所以如果要将ANSI字符转换为UTF-8的话,应该先转Unicode,然后有一对一的编码关系映射为UTF-8。
不过Windows提供了MultiByteToWideChar和WideCharToMultiByte。先用前者把ANSI转换为UTF-16L(Windows内部用的宽字节编码),再用后者指定CP_UTF8来把UTF-16L对应转换为UTF-8
  • 打赏
  • 举报
回复
类型提升呀
printf("%c -- 0x%02x\n", (unsigned char)sresult[z],(unsigned char)sresult[z]);
辰岡墨竹 2011-10-19
  • 打赏
  • 举报
回复
因为你用的是char数组,当把最高为是1的char转int时,符号扩展了,保证是负数。
而你用%x输出时输出的就是补码,所以会显示出一堆f。
unsigned char来存储UTF-8的内容,避免符号扩展,总是当正数处理编码。
freeskyo 2011-10-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 akirya 的回复:]
1 char 是-128 127 ,当某个字节最高位是1 的时候 符号扩展了
2 utf-8是unicode的一种, google utf-8 编码规则
3 只能判断出来非ascii的部分。根据最高位
[/Quote]

具体一点呀,网上n多版本,我都搞不清楚呀,还有上面我分析的那汉字转换的编码对吗,为什么"请字是"
枭- 0xffffffe8
¯ -- 0xffffffaf
· -- 0xffffffb7
  • 打赏
  • 举报
回复
1 char 是-128 127 ,当某个字节最高位是1 的时候 符号扩展了
2 utf-8是unicode的一种, google utf-8 编码规则
3 只能判断出来非ascii的部分。根据最高位

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧