C语言实现URL解码(URLdecode)
URL解码是将URL编码的字符串还原为原始字符串的过程,在C语言中,我们可以实现一个简单的URL解码函数。
实现代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// URL解码函数
char* urldecode(const char *src) {
char *decoded = malloc(strlen(src) + 1);
if (decoded == NULL) {
return NULL;
}
char *dst = decoded;
const char *p = src;
while (*p) {
if (*p == '%' && *(p+1) && *(p+2)) {
// 检查是否是有效的十六进制字符
if (isxdigit(*(p+1)) && isxdigit(*(p+2))) {
char hex[3] = {*(p+1), *(p+2), '\0'};
*dst++ = (char)strtol(hex, NULL, 16);
p += 3;
continue;
}
} else if (*p == '+') {
*dst++ = ' ';
p++;
continue;
}
*dst++ = *p++;
}
*dst = '\0';
return decoded;
}
// 测试函数
int main() {
const char *encoded = "Hello%20World%21%2C%20how%20are%20you%3F";
char *decoded = urldecode(encoded);
if (decoded) {
printf("Encoded: %s\n", encoded);
printf("Decoded: %s\n", decoded);
free(decoded);
} else {
printf("Memory allocation failed\n");
}
return 0;
}
代码说明
-
函数功能:
- 将URL编码的字符串(如
%20表示空格)解码为原始字符串 - 将字符转换为空格
- 处理所有
%XX格式的十六进制编码
- 将URL编码的字符串(如
-
实现细节:
- 使用
malloc分配足够的内存空间(最坏情况下与输入字符串长度相同) - 遍历输入字符串,逐个字符处理
- 遇到时,检查接下来的两个字符是否为有效的十六进制数字
- 使用
strtol将十六进制字符串转换为对应的字符 - 遇到时直接转换为空格
- 使用
-
注意事项:
- 调用者需要负责释放返回的字符串内存
- 函数不处理无效的URL编码(如后跟不足两个字符或非十六进制字符)
- 对于非ASCII字符(如中文),需要确保输入是UTF-8编码的URL编码
更健壮的实现
如果需要更健壮的实现,可以考虑以下改进:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
char* urldecode(const char *src) {
if (src == NULL) return NULL;
size_t src_len = strlen(src);
char *decoded = malloc(src_len + 1);
if (decoded == NULL) return NULL;
char *dst = decoded;
const char *p = src;
while (*p) {
if (*p == '%' && (p + 2 < src + src_len)) {
// 检查是否是有效的十六进制字符
if (isxdigit(*(p+1)) && isxdigit(*(p+2))) {
char hex[3] = {*(p+1), *(p+2), '\0'};
char *endptr;
long val = strtol(hex, &endptr, 16);
if (endptr == hex + 2 && val >= 0 && val <= 255) {
*dst++ = (char)val;
p += 3;
continue;
}
}
} else if (*p == '+') {
*dst++ = ' ';
p++;
continue;
}
*dst++ = *p++;
}
*dst = '\0';
return decoded;
}
这个改进版本增加了对输入指针的NULL检查,并更严格地验证十六进制转换的结果。
