Linux下UTF8和GBK互相转换

不说太多,直接上代码
 

string UTF8ToGBK(const char* strUTF8) {
    const char* to_encoding = "CP936";  // Linux 用 "CP936",Windows 可用 "GBK"
    const char* from_encoding = "UTF-8";

    iconv_t cd = iconv_open(to_encoding, from_encoding);
    if (cd == (iconv_t)-1) {
        throw std::runtime_error("Failed to initialize iconv");
    }

    // 正确的 RAII 管理
    struct IconvGuard {
        iconv_t cd_;
        IconvGuard(iconv_t cd) : cd_(cd) {}
        ~IconvGuard() { if (cd_ != (iconv_t)-1) iconv_close(cd_); }
    } guard(cd);

    size_t in_bytes = strlen(strUTF8);
    size_t out_bytes = in_bytes * 4; // 更安全的缓冲区大小,考虑中文情况
    std::string result(out_bytes, '\0');

    char* in_ptr = const_cast<char*>(strUTF8);
    char* out_ptr = &result[0];
    size_t original_out_bytes = out_bytes;

    if (iconv(cd, &in_ptr, &in_bytes, &out_ptr, &out_bytes) == (size_t)-1) {
        throw std::runtime_error(std::string("Encoding conversion failed: ") + strerror(errno));
    }

    // 调整大小以去除未使用的空间
    result.resize(original_out_bytes - out_bytes);
    return result;
}

string GBKToUTF8(const char* strGBK)
{
	if (strGBK == nullptr) {
		return "";
	}

	iconv_t cd = iconv_open("UTF-8", "GBK");
	if (cd == (iconv_t)-1) {
		throw std::runtime_error("Failed to open iconv descriptor");
	}

	size_t inbytes = strlen(strGBK);
	size_t outbytes = inbytes * 4; // UTF-8最多使用4字节表示一个字符
	std::unique_ptr<char[]> outbuf(new char[outbytes + 1]);

	char* inptr = const_cast<char*>(strGBK);
	char* outptr = outbuf.get();
	memset(outptr, 0, outbytes + 1);

	if (iconv(cd, &inptr, &inbytes, &outptr, &outbytes) == (size_t)-1) {
		iconv_close(cd);
		throw std::runtime_error("Conversion failed");
	}

	iconv_close(cd);
	return std::string(outbuf.get());
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值