posts - 225, comments - 62, trackbacks - 0, articles - 0
   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

用iconv在Linux上进行字符编码转换

Posted on 2019-11-27 18:36 魔のkyo 阅读(205) 评论(0)  编辑 收藏 引用 所属分类: C++
Windows上参考
http://www.cnitblog.com/luckydmz/archive/2010/03/03/64458.html

#include <iconv.h>
#include <cstring>
#include <string>
#include <iostream>

class EncodingConvertor
{
public:
    // "UTF-8", "GBK"
    EncodingConvertor(const char* toEncoding, const char* fromEncoding)
    {
        _iconv = iconv_open(toEncoding, fromEncoding);
    }

    std::string convert(const charin)
    {
        constexpr size_t BLOCK_SIZE = 1024; // iconv可以分块转换,对于特别长的字符串(特别大的文件)
        size_t inlen = strlen(in);
        size_t outbuflen = std::max(inlen * 2, BLOCK_SIZE);
        const char* pin = in;
        char* outbuf = (char*)malloc(outbuflen);
        char* pout = outbuf;

        size_t ret = 0;
        do {
            size_t perlen = BLOCK_SIZE;
            if(pout + perlen > outbuf + outbuflen - 1)
            { // 如果outbuf后面剩余空间不足一个转换块大小,就重新分配空间
                int pout_offset = pout - outbuf;
                outbuflen = std::max(outbuflen * 2, BLOCK_SIZE);
                outbuf = (char*)realloc(outbuf, outbuflen);
                pout = outbuf + pout_offset; // outbuf可能指向新地址,所以要把pout偏移过去
            }
            ret = iconv(_iconv, (char**)&pin, &inlen, &pout, &perlen);
            if(perlen == BLOCK_SIZE)
            { // 转移前后perlen没有变化应该是出错了
                outbuf[0] = 0;
                break;
            }
        } while(ret == -1);
        *pout = 0;
        std::string r(outbuf);
        free(outbuf);
        return r;
    }

    ~EncodingConvertor()
    {
        iconv_close(_iconv);
    }

private:
    iconv_t _iconv;
};

int main()
{
    EncodingConvertor convertor("UTF-8", "GBK");
    std::string s = convertor.convert("GBK string");
    std::cout << s << std::endl;
    return 0;
}


只有注册用户登录后才能发表评论。