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

310 天前
 StubbornHuang

比如返回的 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"
}

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

1574 次点击
所在节点    C++
18 条回复
c2const
310 天前
这是在生成 json 前或生成 json 时,把你的字符串中的\又转义处理了一次吧 :)
StubbornHuang
310 天前
@c2const 用的 nlohmann/json ,这难道还会自动转义?
c2const
310 天前
@StubbornHuang 没用过这个,你可以写个例子或者单步调试跟踪,试一下就知道问题在哪了呗 :)
codehz
310 天前
理论上这个库应该能处理 unicode 的呀
StubbornHuang
310 天前
确实是\被转义成\\了
StubbornHuang
310 天前
@codehz 没看到示例
codehz
310 天前
StubbornHuang
310 天前
@codehz 我现在的处理方式是 nlohmann/json dump 成 std::string 再将\\替换成\
yolee599
310 天前
我怀疑这是一个 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
310 天前
真很显然是 nlohmann/json 自己就有转义功能,所以你从一开始就不应该手写这个中文字符转义的代码,应该直接把原始字符串扔给 nlohmann 让它去做
lonewolfakela
310 天前
真很显然->这很显然(打错字了)
StubbornHuang
309 天前
@lonewolfakela 做不了的,nlohmann/json 默认需要 UTF-8 ,你如果传入 Unicode 是不行的,这在上面老兄发的那个链接: https://json.nlohmann.me/home/faq/#wide-string-handling 就说明,之前也是碰到这个问题才先转的,等于我的接口 io 是 UTF-8 ,但内部字符处理是 Unicode
shuax
309 天前
codehz
309 天前
根据 json 的定义,就是只支持 utf-8 的,你 unicode 通过\u 转义没有改变它表达的还是 utf-8 文本的核心(也就是说不能用来传递非法 utf-8 的字符串),我能想象到的场景是某些信道不支持 utf-8 文本,这种情况下不如在输出 json 文本后进行一个后处理
kirory
309 天前
wstring 不是 Unicode
wstring 不是 Unicode
wstring 不是 Unicode
nlohmann/json 需要 utf-8 encoded string 而不是 wstring
cnbatch
308 天前
要不试试字符串加个 R 前缀,这样就不需要反斜杠转义了。必要时还可以使用 u8 前缀。

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

至于 codecvt 的各种转换,如果只用 C++11 、14 那还能用,从 C++17 开始就被废弃了,C++26 直接删掉,而且这个库无法处理 UTF32 。如果系统内部使用 UTF32 的话那就没法用这个了。
StubbornHuang
308 天前
@cnbatch 好的 感谢提醒 目前定的语言标准是 C++14 只需要注意编译器是否支持

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1009063

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX