老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>
前言
最近看个问题:前端传过来的中文参数是%3D%E9%98%BF%E8%90%A8%E8%BE%BE%26,需要将这个参数转换为中文问题链接
这个应该不陌生,有时候上网看地址栏,经常出现这么一行奇怪的东西,学过编码的都不陌生,这是16进制的数字,就是char的utf8编码,全世界不一定所有地方都有 GBK 编码,但一定有 utf8 编码。
所以通过utf8传递。但为什么搞成字符串形式?因为有些编码不一定能搞成 char 的形式看见,比如a - - z 0 – 9,我们能看见的就那么多,剩下的是各种其他打印不出来的,必须转成可见的char进行传递。
一、开始解码
我们的目的比较简单,就是把字符串 “3D” 转换成数字 “0x3D”,再转换成 char ‘\0x3d’,然后将它们再组成正常的字符串。
直接转换是非常麻烦的,好在 C++ 提供了格式流操作,可以非常简单的进行模式识别,将其转换。
二、流操作
1.引入库
stringstream 可以将字符串格式化为其他类型,比如 int,也可以接受 int 转换为 string
#include <sstream>
2.读入数据
将 “%3D%E9%98%BF%E8%90%A8%E8%BE%BE%26” 作为字符串传给string流:
std::istringstream strToChar(predecStr);
3.转换数据
我们先让string流设定输入格式为 hex,16进制数字。
strToChar >> std::hex;
准备接收字符的string,以及作为分隔符的char,及被转换的 int
std::string resultStr;
char splt;
int utf8ch = 0;
通过如下转换,可以将 字符串的 utf8 转为 char 的utf8
// utf8 字符转 char
while (strToChar >> splt >> utf8ch)
{
resultStr.push_back(static_cast<char>(utf8ch));
}
完整代码
由于 utf8 编码的汉字再windows终端会是乱码,先把终端整成 utf8 语言区域,同时整合其他非中文字符。
#include <iostream>
#include <sstream>
#include <string>
auto decodeURI(const std::string &URIStr) -> std::string
{
std::string temp = URIStr.substr(URIStr.find_first_of('%'));
std::istringstream strToChar(temp);
strToChar >> std::hex;
std::string resultStr;
resultStr.reserve(temp.size() / 3);
char splt;
int utf8ch = 0;
// utf8 字符转 char
while (strToChar >> splt >> utf8ch)
{
resultStr.push_back(static_cast<char>(utf8ch));
}
std::string beginStr = URIStr.substr(0, URIStr.find_first_of('%'));
std::string endStr;
strToChar.clear();
strToChar >> endStr;
if (splt == '%')
{
return beginStr + resultStr;
}
return beginStr + resultStr + splt + endStr;
}
auto main() -> int
{
#ifdef _WIN64
system("chcp 65001");
#endif
std::string str =
R"(http://g.cn/%3D%E9%98%BF%E8%90%A8%E8%BE%BE%26/index.html)";
auto res = decodeURI(str);
std::cout << res << std::endl;
return 0;
}
总结
编码问题一直困扰着很多程序员,还是要多学。
老林的C语言新课, 想快速入门点此 <C 语言编程核心突破>