You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中对含扩展ASCII的std::string进行URL编码的实现方法

我来帮你一步步搞定这个问题——先解决编码转换的坑,再实现字节遍历和URL编码,确保能被JavaScript的decodeURIComponent完美解码。

第一步:将Windows-1252编码的std::string转换为UTF-8

你的原始字符串是基于Windows-1252的扩展ASCII字符,而decodeURIComponent只认UTF-8编码的URL字符串,所以第一步必须完成编码转换。下面是利用MultiByteToWideChar和WideCharToMultiByte的正确实现:

#include <string>
#include <windows.h>

std::string windows1252ToUtf8(const std::string& windows1252Str) {
    // 第一步:Windows-1252转UTF-16(宽字符)
    int wideCharLen = MultiByteToWideChar(CP_WINDOWS_1252, 0, windows1252Str.c_str(), -1, nullptr, 0);
    if (wideCharLen == 0) {
        // 可根据需求替换为异常抛出或其他错误处理
        return "";
    }

    std::wstring wideStr(wideCharLen, L'\0');
    int convertResult = MultiByteToWideChar(CP_WINDOWS_1252, 0, windows1252Str.c_str(), -1, wideStr.data(), wideCharLen);
    if (convertResult == 0) {
        return "";
    }

    // 第二步:UTF-16转UTF-8
    int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, nullptr, 0, nullptr, nullptr);
    if (utf8Len == 0) {
        return "";
    }

    std::string utf8Str(utf8Len, '\0');
    convertResult = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, utf8Str.data(), utf8Len, nullptr, nullptr);
    if (convertResult == 0) {
        return "";
    }

    // 移除转换时自动添加的末尾空字符
    if (!utf8Str.empty() && utf8Str.back() == '\0') {
        utf8Str.pop_back();
    }

    return utf8Str;
}
第二步:遍历UTF-8字符串的单个字节并做URL编码

拿到UTF-8字符串后,遍历字节非常简单——std::string在MSVC里每个char对应一个字节,直接遍历即可。接下来要按照URL编码规则处理每个字节:

  • ASCII安全字符(字母、数字、-_.~)直接保留
  • 其他字符(包括非ASCII的UTF-8字节)转成%XX的十六进制格式

实现代码如下:

#include <sstream>
#include <iomanip>

std::string urlEncodeUtf8(const std::string& utf8Str) {
    std::ostringstream oss;
    oss << std::hex << std::uppercase; // 输出大写十六进制,小写也可兼容JS解码

    for (unsigned char byte : utf8Str) { // 用unsigned char避免符号扩展问题
        // 判断是否为URL安全ASCII字符
        if ((byte >= 'A' && byte <= 'Z') || (byte >= 'a' && byte <= 'z') || 
            (byte >= '0' && byte <= '9') || byte == '-' || byte == '_' || 
            byte == '.' || byte == '~') {
            oss << byte;
        } else {
            // 转成%XX格式,补0确保两位十六进制
            oss << '%' << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
        }
    }

    return oss.str();
}
第三步:整合测试与字节遍历示例

把两个函数结合起来,就能得到可以直接给JS解码的URL编码字符串。如果只是单纯想遍历UTF-8的每个字节,直接用范围for循环即可:

#include <iostream>

int main() {
    std::string originalStr = "čáě"; // 假设此字符串为Windows-1252编码
    std::string utf8Str = windows1252ToUtf8(originalStr);
    std::string encodedStr = urlEncodeUtf8(utf8Str);

    // 遍历并输出UTF-8的每个字节(十六进制)
    std::cout << "UTF-8字节序列:";
    for (unsigned char byte : utf8Str) {
        std::cout << std::hex << std::uppercase << static_cast<int>(byte) << " ";
    }
    std::cout << "\nURL编码结果:" << encodedStr << std::endl;

    // 此时encodedStr传给JS后,decodeURIComponent("%C4%8D%C3%A1%C4%9B")会得到"čáě"
    return 0;
}

内容的提问来源于stack exchange,提问作者freemanovec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:08:58