V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
StubbornHuang
V2EX  ›  C++

关于 C++ http 服务器接口返回中文 unicode 的转义符号问题

  •  
  •   StubbornHuang · 312 天前 · 1578 次点击
    这是一个创建于 312 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如返回的 json 如下

    {
    	"word":"\u4f60\u597d"
    }
    

    这里的 word 是单斜杆的。

    我在 C++中重写了这个 http 服务的接口,但是我只能通过以下的代码将中文转成 unicode 码

    static std::string ConvertWStringToUnicodeEscape(const std::wstring& unicode_str)
    {
    	std::wstring unicode_str_copy = unicode_str;
    	std::stringstream ss;
    	for (std::wstring::iterator iter = unicode_str_copy.begin(); iter != unicode_str_copy.end(); ++iter)
    	{
    		if (*iter <= 127)
    			ss << (char)*iter;
    		else
    			ss << "\\u" << std::hex << std::setfill('0') << std::setw(4) << (int)*iter;
    	}
    
    	return ss.str();
    }
    

    在 C++中输出单斜杠就必须加转义符号,这造成了返回的 json 成了双斜杆

    {
    	"word":"\\u4f60\\u597d"
    }
    

    各位大佬有什么好的解决方法吗?

    18 条回复    2024-01-18 16:26:10 +08:00
    c2const
        1
    c2const  
       312 天前
    这是在生成 json 前或生成 json 时,把你的字符串中的\又转义处理了一次吧 :)
    StubbornHuang
        2
    StubbornHuang  
    OP
       312 天前
    @c2const 用的 nlohmann/json ,这难道还会自动转义?
    c2const
        3
    c2const  
       312 天前
    @StubbornHuang 没用过这个,你可以写个例子或者单步调试跟踪,试一下就知道问题在哪了呗 :)
    codehz
        4
    codehz  
       312 天前
    理论上这个库应该能处理 unicode 的呀
    StubbornHuang
        5
    StubbornHuang  
    OP
       312 天前
    确实是\被转义成\\了
    StubbornHuang
        6
    StubbornHuang  
    OP
       312 天前
    @codehz 没看到示例
    codehz
        7
    codehz  
       312 天前
    StubbornHuang
        8
    StubbornHuang  
    OP
       312 天前
    @codehz 我现在的处理方式是 nlohmann/json dump 成 std::string 再将\\替换成\
    yolee599
        9
    yolee599  
       312 天前
    我怀疑这是一个 X-Y Problem:
    https://coolshell.cn/articles/10804.html

    你需要做的是 wstring 转 string ,仅此而已:

    #include <codecvt>

    static std::string ConvertWStringToUnicodeEscape(const std::wstring& unicode_str)
    {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
    std::string str_new = convert.to_bytes(unicode_str);

    return str_new;
    }
    lonewolfakela
        10
    lonewolfakela  
       312 天前
    真很显然是 nlohmann/json 自己就有转义功能,所以你从一开始就不应该手写这个中文字符转义的代码,应该直接把原始字符串扔给 nlohmann 让它去做
    lonewolfakela
        11
    lonewolfakela  
       312 天前
    真很显然->这很显然(打错字了)
    StubbornHuang
        12
    StubbornHuang  
    OP
       311 天前
    @lonewolfakela 做不了的,nlohmann/json 默认需要 UTF-8 ,你如果传入 Unicode 是不行的,这在上面老兄发的那个链接: https://json.nlohmann.me/home/faq/#wide-string-handling 就说明,之前也是碰到这个问题才先转的,等于我的接口 io 是 UTF-8 ,但内部字符处理是 Unicode
    shuax
        13
    shuax  
       311 天前
    codehz
        14
    codehz  
       311 天前
    根据 json 的定义,就是只支持 utf-8 的,你 unicode 通过\u 转义没有改变它表达的还是 utf-8 文本的核心(也就是说不能用来传递非法 utf-8 的字符串),我能想象到的场景是某些信道不支持 utf-8 文本,这种情况下不如在输出 json 文本后进行一个后处理
    kirory
        15
    kirory  
       311 天前
    wstring 不是 Unicode
    wstring 不是 Unicode
    wstring 不是 Unicode
    nlohmann/json 需要 utf-8 encoded string 而不是 wstring
    cnbatch
        16
    cnbatch  
       310 天前
    要不试试字符串加个 R 前缀,这样就不需要反斜杠转义了。必要时还可以使用 u8 前缀。

    https://en.cppreference.com/w/cpp/language/string_literal
    cnbatch
        17
    cnbatch  
       310 天前
    如果需要字符转码,那就只能用系统自带的转换函数,或者 C 库函数 wcstombs 、wcsrtombs 、mbstowcs

    至于 codecvt 的各种转换,如果只用 C++11 、14 那还能用,从 C++17 开始就被废弃了,C++26 直接删掉,而且这个库无法处理 UTF32 。如果系统内部使用 UTF32 的话那就没法用这个了。
    StubbornHuang
        18
    StubbornHuang  
    OP
       310 天前
    @cnbatch 好的 感谢提醒 目前定的语言标准是 C++14 只需要注意编译器是否支持
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2615 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 15:23 · PVG 23:23 · LAX 07:23 · JFK 10:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.