extern size_t iconv (iconv_t __cd, char **__restrict __inbuf,
size_t *__restrict __inbytesleft,
char **__restrict __outbuf,
size_t *__restrict __outbytesleft);
在使用iconv函数时,没有注意到输出缓冲区和长度剩余的意义,他们都会被修改的。
所以在传参数时,要对原来的输出缓冲区的值和长度保存outbytes,且outbytesleft是移动后的位置,转换的数据长度是原来数据大小 outbytes-outbytesleft。
转换测试代码
cpp
std::string Utils::utf8_to_gbk(const std::string& utf8_str)
{
size_t inbytes = utf8_str.length();
size_t outbytes = inbytes * 2; // 初始估计,可能不够大
size_t outbytes2 = outbytes;
char* outbuf = (char*)malloc(outbytes);
char *outbuf1 = outbuf;
// memset(outbuf,1,outbytes);
if (outbuf == nullptr)
return ""; // 内存分配失败处理
iconv_t cd = iconv_open("GBK", "UTF-8");
if (cd == (iconv_t)-1) {
free(outbuf);
return ""; // iconv打开失败处理
}
char* inbuf = const_cast<char*>(utf8_str.c_str());
memset(outbuf, 0, outbytes);
size_t result = iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes);
iconv_close(cd);
if (result == (size_t)-1) {
free(outbuf);
return ""; // 转换失败处理
}
std::string gbk_str(outbuf1, outbytes2 - outbytes); // 注意这里可能需要调整,因为iconv可能不会在输出末尾添加null终止符
free(outbuf1);
// delete outbuf;
return gbk_str;
}
之前错的代码是
std::string gbk_str(outbuf,outbytes);//这里就是空数据
free(outbuf);//这里就会挂
后来为了实现编码转换功能,使用的是qt的QTextCodec
测试代码,开发环境是linux的qt
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); //设置本地编码是utf-8
QString tmp = "畅行·泉城";//qt中的是unicode编码
qDebug() << "latin " << tmp.toLocal8Bit().toHex(); //utf-8
qDebug() << "latin " << tmp.toUtf8().toHex();//utf-8
size_t c_len = tmp.length();
QByteArray bb = tmp.toUtf8();
// len = bb.length();
std::string aa = tmp.toStdString();//std::string则是utf-8
// 获取UTF-8编解码器
QTextCodec *utf8Codec = QTextCodec::codecForName("UTF-8");
// 获取GBK编解码器
QTextCodec *gbkCodec = QTextCodec::codecForName("GBK");
// 使用UTF-8编解码器将字符串从UTF-8解码为Unicode(QString)
QString unicodeString = utf8Codec->toUnicode(tmp.toUtf8());//这里其实不需要了,只要用下面的就行
// 然后使用GBK编解码器将Unicode字符串编码为GBK
QByteArray gbkByteArray = gbkCodec->fromUnicode(tmp);//qt中已经是unicode编码了
//QByteArray cc;
//cc.append(gbkByteArray);
qDebug() <<gbkByteArray <<"," <<gbkByteArray.toHex();