使用iconv的包装类CharsetConverter进行编码转换的示例

GitHub地址https://github.com/BuYishi/charset_converter_test

charset_converter_test.cpp

#include <iostream>
#include <fstream>
#include "CharsetConverter.h"
int main()
{
    std::string filename("text_utf-8.txt");
    std::ifstream ifs(filename, std::ifstream::in);
    if (ifs)
    {
        std::string line, utf8Text;
        while (std::getline(ifs, line))
            utf8Text.append(line + "
");
        try
        {
            const std::string &converted = CharsetConverter("GBK", "UTF-8").convert(utf8Text);
            std::cout << converted << std::endl;
            filename = "text_gbk.txt";
            std::ofstream ofs(filename, std::ofstream::out);
            if (ofs)
            {
                ofs.write(converted.c_str(), converted.length());
            }
            else
                std::cerr << "Cannot open file: " << filename << std::endl;
        }
        catch (const std::string &ex)
        {
            std::cerr << ex << std::endl;
        }
    }
    else
        std::cerr << "Cannot open file: " << filename << std::endl;
    std::system("pause");
    return 0;
}

CharsetConverter.h

#pragma once
#include <iconv/iconv.h>
#include <string>
class CharsetConverter
{
public:
    CharsetConverter(const char *toCode, const char *fromCode);
    ~CharsetConverter();
    std::string convert(const std::string &source) const;
private:
    iconv_t conversionDescriptor;
};

CharsetConverter.cpp

#include "CharsetConverter.h"
CharsetConverter::CharsetConverter(const char *toCode, const char *fromCode)
{
    conversionDescriptor = iconv_open(toCode, fromCode);
    if (reinterpret_cast<iconv_t>(-1) == conversionDescriptor)
    {
        if (errno == EINVAL)
            throw std::string("Not supported from " + std::string(fromCode) + " to " + toCode);
        else
            throw std::string("Unknown error");
    }
}
CharsetConverter::~CharsetConverter()
{
    iconv_close(conversionDescriptor);
}
std::string CharsetConverter::convert(const std::string &source) const
{
    const char *sourcePtr = source.c_str();
    size_t sourceByteCount = source.length(), totalSpaceOfDestinationBuffer = sourceByteCount * 2, availableSpaceOfDestinationBuffer = totalSpaceOfDestinationBuffer;
    char *destinationBuffer = new char[totalSpaceOfDestinationBuffer], *destinationPtr = destinationBuffer;
    std::string converted;
    size_t convertedCharCount;
    while (sourceByteCount > 0)
    {
        size_t ret = iconv(conversionDescriptor, &sourcePtr, &sourceByteCount, &destinationPtr, &availableSpaceOfDestinationBuffer);
        if (static_cast<size_t>(-1) == ret)
        {
            ++sourcePtr;
            --sourceByteCount;
        }
        convertedCharCount = totalSpaceOfDestinationBuffer - availableSpaceOfDestinationBuffer;
    }
    converted.append(destinationBuffer, convertedCharCount);
    delete[] destinationBuffer;
    return converted;
}
原文地址:https://www.cnblogs.com/buyishi/p/9373906.html