C语言代码实现URL编码

在 Python,只需要导入 urllib.parse,然后使用 quote 函数即可把任意字符串进行 URL 编码

现在使用 C 语言来实现等效的代码,我在网上找到现成的代码,改代码接收命令行输入参数,然后进行 URL 编码并输出:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>

char* urlquote(char* str) {
    size_t len = strlen(str);

    char* result = (char*)malloc((3 * len + 1) * sizeof(char));
    size_t index = 0;

    for (size_t i = 0; i < len; i++) {
        char c = str[i];
        if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~' || c == '/') {
            result[index++] = c;
        }
        else {
            sprintf(&result[index], "%%%02X", (uint8_t)c);
            index += 3;
        }
    }
    result[index] = '\0';
    return result;
}

int main(int argc, char* argv[]) {
    if (argc!=2){
        printf("Usage: urlquote.exe <string>\n\n");
        return 1;
    }
    char* quoted_str = urlquote(argv[1]);
    printf("%s\n", quoted_str);
    free(quoted_str);
    return 0;
}

该代码在 Linux 环境里运行没有问题,输入参数“中”字可以得出正确的编码值:%E4%B8%AD。

然而在 Windows 命令行环境里运行,如果输入半角字符可以得出正确的 URL 编码,但输入字符串只要有中文,得出的结果就截然不同。举个例子,同样的“中”字在 Windows 环境里编码的结果却是:%D6%D0。

这个 D6 D0 是什么?我在其他查询中文编码的网站上得知是 GBK 编码。

“中”字的 UTF-8 编码应该是 E4 B8 AD,三位字节组成。

Windows 和 Linux 环境运行结果不同的原因在于命令行环境的字符编码不同。Linux 以及 C 编译器使用 UTF-8 编码,因此上述代码在 Linux 命令行里输入的参数都能以 UTF-8 编码传入进而转换得出正确的结果。

然而 Windows 的命令行字符编码与本地代码页有关,简体中文的代码页是 GBK(936),Python的 quote 函数实质是按字符串的 UTF-8 字符值进行编码的,上述 C 代码没有考虑什么字符编码环境,仅仅使用当前默认编码,没有正确转换到 UTF-8,所以造成编码结果不同。

因此为了让代码能在 Windows 环境得出正确结果,就必须把传入参数的字符串进行转换成 UTF-8。

由于历史问题,Windows API 库没有一步到位直接把 GBK 转换 UTF-8 的函数,只能 GBK → UniCode → UTF-8 这样来转换。上述代码修改如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <wchar.h>
#include <windows.h>

char* urlquote(char* gbk_str) {
    // 先转换UniCode
    int size_needed = MultiByteToWideChar(CP_ACP, 0, gbk_str, -1, NULL, 0);
    wchar_t* wide_str = (wchar_t*)malloc(size_needed * sizeof(wchar_t));
    MultiByteToWideChar(CP_ACP, 0, gbk_str, -1, wide_str, size_needed);

    // 再转换UTF-8
    size_needed = WideCharToMultiByte(CP_UTF8, 0, wide_str, -1, NULL, 0, NULL, NULL);
    char* utf8_str = (char*)malloc(size_needed);
    WideCharToMultiByte(CP_UTF8, 0, wide_str, -1, utf8_str, size_needed, NULL, NULL);

    size_t len = strlen(utf8_str);
    char* result = (char*)malloc((3 * len + 1) * sizeof(char));
    size_t index = 0;

    for (size_t i = 0; i < len; i++) {
        char c = utf8_str[i];
        if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~' || c == '/') {
            result[index++] = c;
        }
        else {
            sprintf(&result[index], "%%%02X", (uint8_t)c);
            index += 3;
        }
    }

    result[index] = '\0';
    free(wide_str);
    free(utf8_str);
    return result;
}

int main(int argc, char* argv[]) {
    if (argc!=2){
        printf("Usage: urlquote.exe <string>\n\n");
        return 1;
    }
    char* quote_str = urlquote(argv[1]);
    printf("%s\n", quote_str);
    free(quote_str);
    return 0;
}

运行的结果将与 Linux 环境保持一致了,而且与 Python 的 quote 函数相媲美了。

输入参数:"http://xyz.com/?a=壹贰叁&b={\"c=['啊哦呃']\"}"

Python的quote结果:
http%3A//xyz.com/%3Fa%3D%E5%A3%B9%E8%B4%B0%E5%8F%81%26b%3D%7B%22c%3D%5B%27%E5%95%8A%E5%93%A6%E5%91%83%27%5D%22%7D

C在Windows命令行运行结果:
http%3A//xyz.com/%3Fa%3D%E5%A3%B9%E8%B4%B0%E5%8F%81%26b%3D%7B%22c%3D%5B%27%E5%95%8A%E5%93%A6%E5%91%83%27%5D%22%7D

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/249682.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flask基本用法:一个HelloWorld,搭建服务、发起请求

目录 1、简介 2、安装 3、Flask使用示例 参考 1、简介 官网文档 Flask是一个轻量的web服务框架&#xff0c;我们可以利用它快速搭建一个服务&#xff0c;对外提供接口&#xff0c;其他人可以轻松调用我们的服务。这对算法工程师来说比较关键&#xff0c;我们通常不擅长搞开发…

【Docker四】使用Docker-compose一键部署Wordpress平台

目录 一、YAML 文件格式及编写注意事项&#xff08;重要&#xff09; 1、yaml文件使用时注意事项&#xff1a; 2、yaml文件的基本数据结构&#xff1a; 2.1、声明变量&#xff08;标量。是单个的不可再分的值&#xff0c;类型&#xff1a;字符串&#xff0c;整数&#xff0c…

Typescript中Omit数据类型的理解

在 TypeScript 中&#xff0c;Omit 是一个内置的工具类型&#xff0c;它用于从对象类型中排除指定的属性&#xff0c;并返回剩余的属性。 Omit 的语法如下所示&#xff1a; type Omit<T, K> Pick<T, Exclude<keyof T, K>>;其中&#xff0c;T 表示原始类型…

强制性产品认证车辆一致性证书二维码解析

目录 说明 界面 下载 强制性产品认证车辆一致性证书二维码解析 说明 二维码扫描出的信息为&#xff1a; qW0qS6aFjU50pMOqis0WupBnM21DnMxy0dGFN/2Mc9gENXhKh0qEBxFgfXSLoR qW0qS6aFjU50pMOqis0WupBnM21DnMxy0dGFN/2Mc9gENXhKh0qEBxFgfXSLoR 解析后的信息为&#xff1a…

佛山IBM System x3550 M4服务器维修检查

案例背景&#xff1a; 一家位于东莞的制造公司&#xff0c;在其佛山分厂中安装了一台IBM X3550 M4服务器作为其关键业务设备。该服务器负责管理和存储公司的生产数据、ERP系统和供应链数据。在生产过程中&#xff0c;该服务器突然发生了故障&#xff0c;导致佛山分厂的生产中断…

深度学习环境配置

一、Anaconda安装 下载&#xff1a;从清华大学开源软件镜像下载 镜像网址 出现base即为安装成功&#xff1a; 检查显卡的驱动是否正确安装&#xff1a; &#xff08;GPU可以显示出名称&#xff09; GPU0是集显集成显卡是主板自带的显卡。 GPU1是独显即独立显卡&#xff0c…

大数据组件:Hadoop

文章目录 1、Hadoop 是什么2、Hadoop 优势3、Hadoop 组成&#xff08;1&#xff09;HDFS&#xff08;2&#xff09;YARN&#xff08;3&#xff09;MapReduce 架构概述&#xff08;4&#xff09;HDFS、YARN、MapReduce 三者关系&#xff08;5&#xff09;大数据技术生态体系&…

【Java】图片资源转为Base64编码并返回

使用JDK把图片资源转为Base64编码并返回(免费分享&#xff0c;皆可复制粘贴) 在Java实际应用开发过程中&#xff0c;我们需要使用指定的背景图案&#xff0c;例如大型游戏中的一些基本图案&#xff0c;例如礼物、场景、武器造型等等&#xff0c;通俗来说就是图片源文件&#x…

Ubuntu系统的基础操作和使用

#ubuntuUbuntu系统的基础操作和使用包括以下几个方面&#xff1a; 1. 安装和启动&#xff1a;首先&#xff0c;需要下载Ubuntu镜像文件并使用虚拟机软件&#xff08;如VirtualBox&#xff09;创建虚拟机&#xff0c;将镜像文件安装在虚拟机中即可启动Ubuntu系统。 2. 桌面环境…

将开源免费进行到底,ThreadX开源电脑端GUIBuilder图形开发工具GUIX Studio

上个月微软刚刚宣布将ThreadX RTOS全家桶贡献给Eclipse基金会&#xff0c;免费供大家商用&#xff0c;宽松的MIT授权方式&#xff0c;就差这个GUIX Studio没有开源了&#xff0c;而且Windows还经常检索不到&#xff0c;并且也不提供离线包。 1、软件包有点大&#xff0c;700MB…

初识Pandas函数是Python的一个库(继续更新...)

学习网页&#xff1a; Welcome to Python.orghttps://www.python.org/https://www.python.org/https://www.python.org/ Pandas函数库 Pandas是一个Python库&#xff0c;提供了大量的数据结构和数据分析工具&#xff0c;包括DataFrame和Series等。Pandas的函数非常丰富&…

BI技巧丨钻取动态度量值

PowerBI自带的数据钻取功能&#xff0c;在实际应用中是用户使用度较高的功能之一&#xff0c;特别是需要实际操作的业务用户&#xff0c;往往需要根据汇总的结果定位到相关的明细数据&#xff0c;以便进行下一步的流程操作&#xff0c;这种场景下钻取功能显得尤为便利。 关于钻…

掌握魔法绘制图片、PDF剪辑器功能,智能生成AI文章,高效工作从此开始

在这个信息爆炸的时代&#xff0c;如何高效地处理和利用各种文件格式成为了我们日常工作的关键。今天&#xff0c;我们将为您介绍一款强大的工具&#xff0c;它能够智能生成AI文章&#xff0c;高效掌握魔法绘制图片和PDF剪辑器功能&#xff0c;为您的工作带来前所未有的便捷和高…

【送书活动】智能汽车、自动驾驶、车联网的发展趋势和关键技术

文章目录 前言01 《智能汽车》推荐语 02 《SoC底层软件低功耗系统设计与实现》推荐语 03 《SoC设计指南》推荐语 05 《智能汽车网络安全权威指南&#xff08;上册&#xff09;》推荐语 06 《智能汽车网络安全权威指南&#xff08;下册&#xff09;》推荐语 后记赠书活动 前言 …

jmeter,同一线程组内,调用cookie实现接口关联

取cookie方式参考上一篇&#xff1a;jemeter&#xff0c;取“临时重定向的登录接口”响应头中的cookie-CSDN博客 元件结构 登录后要执行的接口为“api/get_event_list/”&#xff0c;在该HTTP请求下创建HTTP信息头管理器&#xff0c;配置如下&#xff1a; 执行测试后&#xff0…

太阳能电池特性测试用太阳光模拟器24H光源

概述 太阳能模拟器是一种在室内模拟太阳光的设备&#xff0c;能够较为准确地模拟太阳辐射的准直性、均匀性和光谱特性。它的基本原理是利用人工光源模拟太阳光辐射&#xff0c;以克服太阳光辐射受环境、时间和气候等因素影响&#xff0c;并且总辐照度不能调节等缺点&#xff0c…

【NSX-T】10. 搭建NSX-T环境 —— 使用 BGP 配置 Tier-0 网关

目录 10.1 创建上行链路网段10.2 创建 Tier-0 网关&#xff08;1&#xff09;设置 Interface 信息&#xff08;2&#xff09;设置 BGP添加 BGP 邻居 &#xff08;3&#xff09;设置 BGP 路由重分发设置路由重新分发 10.3 连接 Tier-0 和 Tier-1 网关10.4 使用网络拓扑验证 Tier…

【树莓派】高级开发概述、开发环境搭建(内核镜像拷贝至树莓派并启动新内核)

一、树莓派开发环境搭建 二、Linux文件系统的目录结构 三、树莓派Linux源码目录树分析 四、树莓派Linux源码配置 五、如何配置树莓派的Linux内核 六、树莓派Linux内核编译 七、配置启动参数的cmdline.txt 一、树莓派开发环境搭建 树莓派官网 raspberrypi raspberrypi/tools…

laravel的安装

laravel的安装&#xff08;Composer小皮&#xff09; Composer的安装 windows下安装 https://getcomposer.org/Composer-Setup.exe 修改镜像 阿里云&#xff1a; composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 华为云&#xff1a; compos…

如何实现免费的文档翻译

文中有彩蛋&#xff0c;请一定要看完。 目录 文中有彩蛋&#xff0c;请一定要看完。 一、问题的提出 二、文档翻译现状 三、如何免费海量文档翻译 1. 采用CAT工具机器翻译API法 2. 采用小牛文档翻译 四、学后反思 一、问题的提出 随着互联网和人工智能技术的飞速发展&…