打开百度,你在搜索栏中输入“芙蓉妹妹”,你看到了什么?是不是看到了下面的东东?
%DC%BD%C8%D8%C3%C3%C3%C3&cl=3
哦,那么这个"%DC%BD%C8%D8%C3%C3%C3%C3"是什么玩意呢? 聪明的你可能已经猜到了,它就是“芙蓉妹妹”这四个字,那么为什么是这样的呢?
网页中通过url传递后的参数就会将其编码,URL 编码是一种浏览器用来打包表单输入的格式. 浏览器从表单中获取所有的name和其中的值,将他们作为name/value参数编码,
移去那些不能传送的字符, 将数据排行等等,这些还取决于你用GET还是POST?作为URL的一部分或者分离地发给服务器. 不管哪种情况,
在服务器端的表单输入格式样子象这样:
这是一个专门对地址栏里所传递的参数进行编码的规则。比如在参数中带有空格的话,传递参数时就会发生错误,而用URL编码过以后,空格变成了%20这样就不会发生错误了;另外中文字经编码后全是怪符号,有利于保密。这个编码后的字串提交给服务器后是不需要解码的,网页会自动识别。
URL编码遵循下列规则:
每对name/value由&符分开.每对来自表单的name/value由=符分开.
如果用户没有输入值给这个name,那么这个name还是出现,只是无值(象这样
"name=").任何特殊的字符(就是那些不是简单的七位ASCII,如汉字) 将以百分符%用十六进制编码. 当然也包括象 =, &,
和 %
这些特殊的字符.在输入区中的空格将以加号+显示.
因为表单输入是用这个URL编码传递给你的脚本的,在你用这些参数之前必须解码,虽然解码是个很普遍的
工作,但是你在用c语言从stdin中获取了这些参数之后,如果是汉字的话,你必须自己解码。那么如何解码呢?
请看下面的示例程序:
/* decodeurl.c */
#include
#include
#include
void url2char(unsigned char *surl, unsigned char *res);
int h2i(char *s);
int main()
{
char str[] = "%DC%BD%C8%D8%C3%C3%C3%C3"; // 这个是url中的汉字编码结果
char res[256];
url2char(str, res); //解码
printf("%s", res); // 打印解码后的汉字
return 0;
}
/*将16进制表示的汉字编码解码为汉字, 该函数只适用于纯汉字字符串*/
void url2char(unsigned char *surl, unsigned char *res)
{
unsigned char hex[256];
int i, j, nlen;
unsigned char tmp[3];
// 首先去掉所有的百分号
nlen = (int)strlen(surl);
j = 0;
for ( i = 0; i < nlen; i++ )
{
if ( surl[i] == '%' )
continue;
hex[j++] = surl[i];
}
hex[j] = 0;
nlen = (int)strlen(hex);
j = 0;
// 将每2个16进制数转换成一个10进制数(打印出来就是汉字)
for ( i = 0; i < nlen; i += 2)
{
tmp[0] = hex[i];
tmp[1] = hex[i+1];
tmp[2] = 0;
res[j++] = h2i(tmp);
}
res[j] = 0;
}
int h2i(char *s)
{
char *digits="0123456789ABCDEF";
if (islower (s[0])) s[0]=toupper(s[0]); /* 判断是否是小写字母,是则转换成大写 */
if (islower (s[1])) s[1]=toupper(s[1]);
return 16*(strchr(digits,s[0])-strchr(digits,'0'))
+ (strchr(digits,s[1])-strchr(digits,'0')); /* 返回相应十进制数 */
}
程序运行的结果是:
芙蓉妹妹
上面的是纯汉字的字符串的解码,如果字符串中含有英文字符或者其它的字符呢?
则用下面的方法解码:
void url2char(unsigned char *surl, unsigned char *res)
{
int i, j, nlen;
unsigned char tmp[3];
nlen = (int)strlen(surl);
j = 0;
for ( i = 0; i < nlen; )
{
if ( surl[i] == '%' )//以%开头的是汉字或者其它特殊字符
{
tmp[0] = surl[i+1];
tmp[1] = surl[i+2];
tmp[2] = 0;
i += 3;
res[j] = h2i(tmp);
}
else // 英文字符,直接拷贝
{
res[j] = surl[i];
i++;
}
j++;
}
res[j] = 0;
}
在一般的中文网页中,比如百度,用的gb2312字符集,百分号加上2个16进制数代表一个汉字,把两个16进制数转换成10进制数,而一个Ansi字符就是一个无符号的整数,所以这些整数以字符串的形式连续打印出来就是你想要的汉字。
本文参考了http://oss.lzu.edu.cn/blog/article.php?tid_269.html一文。
附:C/C++里怎样判断字符串中含有汉字
该部分来源于http://blog.chinaunix.net/u/553/showart_225299.html
看字符的编码规范;GB2312的汉字以大于0x80的字节开始
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int first(unsigned char ch)
{
if(ch>=0xb0&&ch<=0xf7)
return 1;
else
return 0;
}
int second(unsigned char ch)
{
if(ch>=0xa1&&ch<=0xfe)
return 1;
else
return 0;
}
int check(const char* p)
{
int i=0;
for(i=0;i<strlen(p)-1;i++)
if(first(p[i])&&second(p[i+1]))
return 1;
return 0;
}
main()
{
const char* str= "sdfddfsdf";
check(str)?puts("there has character!"):puts("there has none character!");
}
|
适用于GB2312字符集,
可修改first和second函数,使适用于其他字符集:)
一种可能是小于0xb0而大于0x80 ,那是GB2312中的其他字符,而非汉字.包括西文...
另一种可能是乱码(该字符串因为未知的原因丢失了第二位,产生乱码)
阅读(5371) | 评论(2) | 转发(0) |