zoukankan      html  css  js  c++  java
  • 关于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

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

  • 相关阅读:
    SVN库迁移整理方法----官方推荐方式
    SVN跨版本库迁移目录并保留提交日志
    微信公众号 发送图文消息
    Egret白鹭开发微信小游戏排行榜功能
    双滑动列表实现
    unity之资深工程师
    unity之高级工程师
    lua踩坑系列之浅拷贝与深拷贝
    lua之table.remove你不知道的坑
    unity之Layout Group居中显示
  • 原文地址:https://www.cnblogs.com/geekma/p/2662233.html
Copyright © 2011-2022 走看看