我正在构建一个通过tcp接收带编码unicode的运行时字符串的应用程序,示例字符串将是“\ u7cfb \ u8eca \ u4e21 \ uff1a \ u6771 \ u5317 ...”。我有以下内容,但遗憾的是,我只能在编译时受益于:由于:不完整的通用字符名称\ u,因为它在编译时需要4个十六进制字符。
QString restoreUnicode(QString strText)
{
QRegExp rx("\\\\u([0-9a-z]){4}");
return strText.replace(rx, QString::fromUtf8("\u\\1"));
}
我正在寻找运行时的解决方案,我可以预见破坏这些字符串并进行一些操作以将“\ u”分隔符之后的那些十六进制转换为基数10然后将它们传递给QChar的构造函数但是我我正在寻找一种更好的方式,因为我非常担心这种方法所带来的时间复杂性而且不是专家。
有没有人有任何解决方案或提示。
答案 0 :(得分:1)
你应该自己解码字符串。只需获取Unicode条目(rx.indexIn(strText)
),解析它(int result; std::istringstream iss(s); if (!(iss>>std::hex>>result).fail()) ...
并将原始字符串\\uXXXX
替换为(wchar_t)result
。
答案 1 :(得分:1)
#include <assert.h>
#include <iostream>
#include <string>
#include <sstream>
#include <locale>
#include <codecvt> // C++11
using namespace std;
int main()
{
char const data[] = "\\u7cfb\\u8eca\\u4e21\\uff1a\\u6771\\u5317";
istringstream stream( data );
wstring ws;
int code;
char slashCh, uCh;
while( stream >> slashCh >> uCh >> hex >> code )
{
assert( slashCh == '\\' && uCh == 'u' );
ws += wchar_t( code );
}
cout << "Unicode code points:" << endl;
for( auto it = ws.begin(); it != ws.end(); ++it )
{
cout << hex << 0 + *it << endl;
}
cout << endl;
// The following is C++11 specific.
cout << "UTF-8 encoding:" << endl;
wstring_convert< codecvt_utf8< wchar_t > > converter;
string const bytes = converter.to_bytes( ws );
for( auto it = bytes.begin(); it != bytes.end(); ++it )
{
cout << hex << 0 + (unsigned char)*it << ' ';
}
cout << endl;
}
答案 2 :(得分:1)
对于关闭以及将来遇到此线程的任何人,在优化这些变量的范围之前,这是我的初始解决方案。不是它的粉丝,但它的工作原理是unicode和/或ascii在我无法控制的流中的不可预测性(仅限客户端),而Unicode存在性低,处理它而不是丑陋的\ u1234等
QString restoreUnicode(QString strText)
{
QRegExp rxUnicode("\\\\u([0-9a-z]){4}");
bool bSuccessFlag;
int iSafetyOffset = 0;
int iNeedle = strText.indexOf(rxUnicode, iSafetyOffset);
while (iNeedle != -1)
{
QChar cCodePoint(strText.mid(iNeedle + 2, 4).toInt(&bSuccessFlag, 16));
if ( bSuccessFlag )
strText = strText.replace(strText.mid(iNeedle, 6), QString(cCodePoint));
else
iSafetyOffset = iNeedle + 1; // hop over non code point to avoid lock
iNeedle = strText.indexOf(rxUnicode, iSafetyOffset);
}
return strText;
}