文档章节

fstream类读取UTF-8、Unicode和ANSI文本文档乱码问题的解决方案

Yong_Luo
 Yong_Luo
发布于 2011/05/28 10:54
字数 579
阅读 7271
收藏 2

1、解决UTF-8类型的文本文档中文乱码读取(思路:将UTF-8转成Unicode然后再转ANSI)

#include <fstream>
#include <iostream>
#include <string>
// #include <afx.h>
#include <Windows.h>

//changeTextFromUtf8ToAnsi读取UTF-8格式的文件并将之保存为ANSI格式的文件

void changeTextFromUtf8ToAnsi(const char* filename)
{
ifstream infile;string strLine="";string strResult="";
infile.open(filename);
if (infile)
{
   while(!infile.eof()){
    getline(infile,strLine);
    strResult+=strLine+"\n";
   }
}
infile.close();
char* changeTemp=new char[strResult.length()];
strcpy(changeTemp,strResult.c_str());
char* changeResult=changeTxtEncoding(changeTemp);
strResult=changeResult;

ofstream outfile;
outfile.open("I:\\ANSI.txt");
outfile.write(strResult.c_str(),strResult.length());
outfile.flush();
outfile.close();
}

//changeTxtEncoding修改字符串的编码

char* changeTxtEncoding(char* szU8){
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
wchar_t* wszString = new wchar_t[wcsLen + 1];
::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
wszString[wcsLen] = '\0';
cout<<wszString<<endl;


int ansiLen = ::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
char* szAnsi = new char[ansiLen + 1];
::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), szAnsi, ansiLen, NULL, NULL);
szAnsi[ansiLen] = '\0';
return szAnsi;
}

2、解决Unicode类型的文本文档中文乱码读取(此方法经测试不可用于打开ANSI的文本文档)

string ws2s(const std::wstring& ws)和string readTxt(char* filename)函数转帖自CSDN,readTxt函数由本人进行了一个小小的bug修正,从而可以避免末字符重复出现的问题;

// fstream中文乱码解决方案.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
string ws2s(const std::wstring& ws);
string readTxt(char* filename);
int _tmain(int argc, _TCHAR* argv[])
{
readTxt("E:\\testUnicode.txt");
}


std::string ws2s(const std::wstring& ws)
{
std::string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest,0,_Dsize);
wcstombs(_Dest,_Source,_Dsize);
std::string result = _Dest;
delete []_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}

std::string readTxt(char* filename) {
ifstream fin;
fin.open(filename, ios::binary);
size_t index = 2;
std::string strRet;
std::string strLineAnsi;
std::wstring wstrLine;

while (!fin.eof())
{
   fin.seekg(index, ios::beg);
   wchar_t wch;
   fin.read((char *)(&wch), 2);
   if (wch == 0x000D) // 判断回车
   {
    strLineAnsi = ws2s(wstrLine);
    wstrLine.erase(0, wstrLine.size() + 1);
    index += 2; // 跳过回车符和行开头符
    strRet = strRet + strLineAnsi;
   }
   else
   {
    wstrLine.append(1, wch);
    index += 2;
   }
}
strLineAnsi = ws2s(wstrLine);
strRet = strRet + strLineAnsi;
fin.close();
//if语句解决文本段末有回车导致最后字符集重复的问题
if (strLineAnsi!="")
{
   strRet=strRet.substr(0,strRet.length()-1);
}
printf("%s", strRet.c_str());
return strRet;
}

3、解决ANSI类型的文本文档中文乱码读取(此方法经测试不可用于打开Unicode的文本文档)

#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
ifstream infile;
string strResult="";
string strTemp="";
infile.open("E:\\testANSI.txt");
if (infile)
{
   while(!infile.eof())
   {
        getline(infile,strTemp);
     strResult+=strTemp;
   }
}
infile.close();
cout<<strResult;
}

本文转载自:http://hi.baidu.com/shi074185/blog/item/4124976224fb90cf8db10d18.html

Yong_Luo
粉丝 13
博文 123
码字总数 1875
作品 0
海淀
私信 提问
加载中

评论(1)

vaint
vaint
79解决了我的一个问题
VIM查看中文编码文件显示为乱码的解决办法

修改你的.vimrc文件,让其支持 gb2312就行,会自动识别的。 可以参考我的设置 代码: "设定文件编码类型,彻底解决中文编码问题 let &termencoding=&encoding set fileencodings=utf-8,gbk,uc...

ldhshao
2013/06/17
237
0
(转)字符编码详解——彻底理解掌握编码知识,“乱码”不复存在

每一个程序员都不可避免的遇到字符编码的问题,特别是做Web开发的程序员,“乱码问题”一直是让人头疼的问题,也许您已经很少遇到“乱码”问题,然而,对解决乱码的方法的内在原理,您是否明...

天蚕宝衣
2016/03/09
88
0
java 常见中文乱码问题解决

关于中文乱码: 一、 1).在jsp页面上输入中文,要保证中文不乱码,有三个前提: 保证contentType=“text/html;charset=UTF-8”,pageEncoding=“UTF-8” charset和pageEncoding的编码一致,...

祁猛
2016/11/07
85
0
Java 读取、写入文件——解决乱码问题

读取文件流时,经常会遇到乱码的现象,造成乱码的原因当然不可能是一个,这里主要介绍因为文件编码格式而导致的乱码的问题。首先,明确一点,文本文件与二进制文件的概念与差异。 文本文件是...

learn_more
2015/03/09
16.6K
3
python的中文编码问题

我很想就这个问题做个详细的解释,但也许水平有限,解释的不是很清楚,甚至自己理解的都不正确,那么我将长期修改 我使用pyscripter来作为编辑器,首先在pyscriter上打上这么一行代码 运行,...

晨曦之光
2012/04/13
2.4K
1

没有更多内容

加载失败,请刷新页面

加载更多

使用CSS自定义属性构建骨架屏

写在前面 几天前看到薄荷前端团队分享的《前端骨架屏方案小结》,突然回想起一年前看到的max bock写的《Building Skeleton Screens with CSS Custom Properties》,翻译整理写下出此文,分享...

前端老手
昨天
9
0
Docker常用命令小记

除了基本的<font color="blue">docker pull</font>、<font color="blue">docker image</font>、<font color="blue">docker ps</font>,还有一些命令及参数也很重要,在此记录下来避免遗忘。 ......

程序员欣宸
昨天
9
0
MAT使用-jvm内存溢出问题分析定位

1.MAT简介: MAT 全称 Eclipse Memory Analysis Tools 是一个分析 Java堆数据的专业工具,可以计算出内存中对象的实例数量、占用空间大小、引用关系等,看看是谁阻止了垃圾收集器的回收工作,...

xiaomin0322
昨天
5
0
内网和外网之间的通信(端口映射原理)

首先解释一下“内网”与“外网”的概念: 内网:即所说的局域网,比如学校的局域网,局域网内每台计算机的IP地址在本局域网内具有互异性,是不可重复的。但两个局域网内的内网IP可以有相同的...

Jack088
昨天
6
0
3.深入jvm内核-原理、诊断与优化-4. GC算法和种类

一、GC算法和种类 GC的概念 GC算法 引用计数法 标记清除 标记压缩 复制算法 可触及性 Stop-The-World GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法 通过引用计算来回收垃圾 使用者...

hexiaoming123
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部