2011-09-07
url提交信息为何要转码呢?因为url本身会有很多特殊字符。而提交的参数中如果再有特殊字符的话,url就不能区分哪些是参数内容,哪些是分隔符。尤其是unicode,gb18030,big5等多字节的编码,不知道里面会隐藏什么字节,因此必须全部转码。
好像C语言里面没有现成的转码函数。参考张老师专栏,从php的转码中引出两个函数,进行转码。
字符”a”-“z”,”A”-“Z”,”0”-“9”,”.”,”-“,”*“,和”_” 都不被编码,维持原值; 空格” “被转换为加号”+”。 其他每个字节都被表示成”%xy”格式的由3个字符组成的字符串,编码为UTF-8。
头文件
int url_decode(char *str, int len);
char *url_encode(char const *s, int len, int *new_length);
c 文件:
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
/*
本文代码为从PHP代码中修改而来,只保留了2个函数。
int url_decode(char *str, int len);
char *url_encode(char const *s, int len, int *new_length);
URL编码做了如下操作:
字符"a"-"z","A"-"Z","0"-"9",".","-","*",和"_" 都不被编码,维持原值;
空格" "被转换为加号"+"。
其他每个字节都被表示成"%xy"格式的由3个字符组成的字符串,编码为UTF-8。
*/
static unsigned char hexchars[] = "0123456789ABCDEF";
static int htoi(char *s)
{
int value;
int c;
c = ((unsigned char *)s)[0];
if (isupper(c))
c = tolower(c);
value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
c = ((unsigned char *)s)[1];
if (isupper(c))
c = tolower(c);
value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
return (value);
}
char *url_encode(char const *s, int len, int *new_length)
{
register unsigned char c;
unsigned char *to, *start;
unsigned char const *from, *end;
from = (unsigned char *)s;
end = (unsigned char *)s + len;
start = to = (unsigned char *) calloc(1, 3*len+1);
while (from < end)
{
c = *from++;
if (c == ' ')
{
*to++ = '+';
}
else if ((c < '0' && c != '-' && c != '.') ||
(c < 'A' && c > '9') ||
(c > 'Z' && c < 'a' && c != '_') ||
(c > 'z'))
{
to[0] = '%';
to[1] = hexchars[c >> 4];
to[2] = hexchars[c & 15];
to += 3;
}
else
{
*to++ = c;
}
}
*to = 0;
if (new_length)
{
*new_length = to - start;
}
return (char *) start;
}
int url_decode(char *str, int len)
{
char *dest = str;
char *data = str;
while (len--)
{
if (*data == '+')
{
*dest = ' ';
}
else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2)))
{
*dest = (char) htoi(data + 1);
data += 2;
len -= 2;
}
else
{
*dest = *data;
}
data++;
dest++;
}
*dest = '/0';
return dest - str;
}
使用方式:
#include <wininet.h>
//定义一个发送函数
void PostHttpRequest(const char* url, const char* param)
{
HINTERNET hSession = InternetOpen("MobileAgent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if ( hSession != NULL )
{
HINTERNET hConnection = InternetConnect(hSession,
url,
INTERNET_DEFAULT_HTTP_PORT,
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
NULL);
if ( hConnection != NULL )
{
HINTERNET hRequest = HttpOpenRequest(hConnection,
"POST",
param,
NULL,
NULL,
(const char**)"*/*\0",
0,
NULL);
if ( hRequest != NULL )
{
HttpSendRequest(hRequest, NULL, 0, NULL, 0);
InternetCloseHandle(hRequest);
}
InternetCloseHandle(hConnection);
}
InternetCloseHandle(hSession);
}
}
#define URL_ADDFEEDBACK ("http://abloz.com/")
void sendurl()
{
char buf[MAX_PATH];
char szUserName[MAX_PATH]={"周海汉 ablozhou abloz.com"};
char szContent[MAX_PATH]={"这什么网站啊?尽是些乱码dja;a d;404 &^$ # %$()!~?'、%“”;"};
int lenu = strlen(szUserName);
int lenc = strlen(szContent);
sprintf(buf, "test.php?username=%s&content;=%s", url_encode(szUserName,lenu,&lenu),url_encode(szContent,lenc,&lenc));
PostHttpRequest(URL_ADDFEEDBACK,buf);
}
本文在window7 下用vs 2010编译测试通过。
如非注明转载, 均为原创. 本站遵循知识共享CC协议,转载请注明来源
FEATURED TAGS
css
vc6
http
automake
linux
make
makefile
voip
乱码
awk
flash
vista
vi
vim
javascript
pietty
putty
ssh
posix
subversion
svn
windows
删除
编译
多线程
wxwidgets
ie
ubuntu
开源
c
python
bash
备份
性能
scp
汉字
log
ruby
中文
bug
msn
nginx
php
shell
wordpress
mqueue
android
eclipse
java
mac
ios
html5
js
mysql
protobuf
apache
hadoop
install
iocp
twisted
centos
mapreduce
hbase
thrift
tutorial
hive
erlang
lucene
hdfs
sqoop
utf8
filter
草原
yarn
ganglia
恢复
scrapy
django
fsimage
flume
tail
flume-ng
mining
scala
go
kafka
gradle
cassandra
baas
spring
postgres
maven
mybatis
mongodb
https
nodejs
镜像
心理学
机器学习
Keras
theano
anaconda
docker
spark
akka-http
json
群论
区块链
加密
抽象代数
离散对数
同余
欧拉函数
扩展欧几里德算法
ES6
node-inspect
debug
win10
vscode
挖矿