关于c++的文件编码的研究

    今天很有成就感,倒不是做出了多牛的东西,而是终于可以动态的进行编码的各种转换了。

    其实这个用到的是网上一搜一大片的iconv,目前有windows版和linux版,linux下的很容易找到,直接装上就可以进行开发了,windows下的包可以通过这个链接下载:win-iconv-0.0.4.zip,直接将放入工程内,就可以使用了。

     下面给出我自己的测试代码(基于文件的):

#include <iostream>

#include <stdlib.h>

#include <stdio.h>

#include <fstream>

#include "include/iconv.h"



using namespace std;



int main(void)  

{

    string src("");

    char buf[4096];

    int fileLen = 0;

    ifstream file1("sohu.htm");

    while(!file1.eof())

    {

        memset(buf, 0, 4096);

        file1.read(buf, 4096);             

        int readLen = file1.gcount();

        buf[readLen] = '\0';

        printf("readline: \n %s\n", buf);     

        src.append(buf);

        fileLen += readLen;

    }

    

    file1.close();

    char *dest = new char[src.length() * 2 + 1]; /* 格式化转换后的字串 */  

    memset(dest, 0, src.length() * 2 + 1);

    size_t src_len = src.length();  

    size_t dst_len = src.length() * 2;          //注意:我用了一块2倍于源数据长度的buffer 

    const char *in = src.c_str();  

    char *out = dest;  

      

    iconv_t cd;

      

    cd = iconv_open("utf-8", "gb2312");         /* 将GB2312字符集转换为UTF-8字符集 */  

    if ((iconv_t)-1 == cd)

    {  

        printf("iconv_open err %d\n", errno);

        return -1;  

    }  

  

    if(iconv(cd, &in, &src_len, &out, &dst_len) == -1) /* 执行转换 */ 

    {  

        printf("iconv_open err %d\n", errno);

        return -1;  

    }  



    ofstream file2("out.txt");

    file2.write(dest, src.length() * 2 - dst_len);

    file2.close();

      

    iconv_close(cd); /* 执行清理 */  

    return 0;  

}  

 我在写代码的时候,遇到了两种错误:

(1)返回errno=7,即E2BIG

    问题原因:目的内存的大小不够

    解决办法:就是使用的分配2倍于源数据大小的空间,由于编码转换会导致数据量的变化

(2)返回errno=42,即ENOMSG

    问题原因:源数据的编码与iconv_open输入的源编码不同

    解决办法:就是找到源数据的真正编码,使用uchardet对字符串进行分析得出真正的编码格式

如何使用uchardet?

uchardet_t m_uchardet = uchardet_new();

if(m_uchardet)

{

    if(uchardet_handle_data(m_uchardet, m_content.c_str(), m_content.length()) == 0)

    {

         uchardet_data_end(m_uchardet);

         m_charSet.assign(uchardet_get_charset(m_uchardet));

    }

}

uchardet_delete(m_uchardet);

uchardet源码下载路径:

BYVoid-uchardet-56a4c0d.zip

类似的,对内存中的数据进行编码转换也可以用这个方法,最终输出的文件编码格式就是当初设置的目标编码格式。

你可能感兴趣的:(文件编码)