`
bjwyl66
  • 浏览: 15853 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

C++读取和处理UTF-8格式文件的方法

    博客分类:
  • c++
c++ 
阅读更多
关于UTF-8、GB2313、ANSI、UNICODE的编码问题,在此不多说,百度上资料很多的。
以下为源代码:
// UtfFile.h: interface for the UtfFile class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_UTFFILE_H__8ED10D8A_D1A3_412F_A600_124F521CE4F1__INCLUDED_)
#define AFX_UTFFILE_H__8ED10D8A_D1A3_412F_A600_124F521CE4F1__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <windows.h> 
#include <stdio.h>
#include <locale.h>
#include <IOSTREAM>
#include <FSTREAM>
using namespace std;

class UtfFile 
{
public:
 static char * UnicodeToGB2312(WCHAR uData, char buffer[2]);  // Unicode 转换成 GB2312
 static WCHAR * UTF_8ToUnicode(char *pText, WCHAR &unicode);  // 把UTF-8 转化成 Unicode
 static char * TranslateUTF8ToGB(char *str, size_t len);   // 把UTF-8字符串转化成ANSI(GB2312)编码形式
 char * GetString(char *str, int maxLen = 1024);  // 读取一个字符串,以换行符为结束标示
 char * GetLine(char *str, int maxLen);    // 读取一行字符
 void close();          // 关闭文件流
 int open(const char *sFileName);     // 用于打开一个文件
 UtfFile(const char *sour);
 virtual ~UtfFile();
 
private:
 ifstream inf;
};

#endif // !defined(AFX_UTFFILE_H__8ED10D8A_D1A3_412F_A600_124F521CE4F1__INCLUDED_)

 

/*-----------------------------------------------以下为.cpp文件内容------------------------------------------*/

// UtfFile.cpp: implementation of the UtfFile class.
//
//////////////////////////////////////////////////////////////////////

#include "UtfFile.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

UtfFile::UtfFile(const char *sour)
:inf(sour)
{
 if( !inf.is_open() )
 {
  char str[1024];
  sprintf(str, "错误的文件路径,文件无法打开:%s", sour);
  throw runtime_error(str);
 }
}

UtfFile::~UtfFile()
{

}

void UtfFile::close()
{
 inf.close();
}


char * UtfFile::GetLine(char *str, int maxLen)
{
 if ( inf.eof() )
 {
  str[0] = '\0';
 }
 else
 {
  inf.getline(str, maxLen);
  TranslateUTF8ToGB(str, maxLen);
 }
 return str;
}


char * UtfFile::GetString(char *str, int maxLen)
{
 if ( inf.eof() )
 {
  str[0] = '\0';
 }
 else
 {
  inf >> str;
  TranslateUTF8ToGB(str, maxLen);
 }
 return str;
}

 

char * UtfFile::UnicodeToGB2312(WCHAR uData, char buffer[2])
{
 WideCharToMultiByte(CP_ACP,NULL, &uData, 1,buffer,sizeof(WCHAR),NULL,NULL);
 return buffer;
}

WCHAR * UtfFile::UTF_8ToUnicode(char *pText, WCHAR &unicode)
{ 
/*    http://blog.csdn.net/liuzhiyuan1982/article/details/3911150
UTF-8是一种多字节编码的字符集,表示一个Unicode字符时,它可以是1个至多个字节,在表示上有规律:
1字节:0xxxxxxx
2字节:110xxxxx 10xxxxxx
3字节:1110xxxx 10xxxxxx 10xxxxxx
4字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
 char *uchar = (char *)&unicode; 
 uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
 uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);
 return &unicode;
}

char * UtfFile::TranslateUTF8ToGB(char *str, size_t len)
{
 char * newCharBuffer = new char[len];
 int index =0;
 int nCBIndex = 0;
 WCHAR wTemp = 0;
 char cTemp[2] = " ";
 while(index < len)
 {
  if ( str[index] == 0 )
   break;
  else if(str[index] > 0)  // 如果是GB2312的字符
  {
   newCharBuffer[nCBIndex] = str[index];    //直接复制
   index += 1;    //源字符串偏移量1
   nCBIndex += 1;   //目标字符串偏移量1
  }
  else      //如果是UTF-8的字符
  {
   UTF_8ToUnicode(str + index, wTemp);   //先把UTF-8转成Unicode
   UnicodeToGB2312(wTemp, &newCharBuffer[nCBIndex]); //再把Unicode 转成 GB2312
   index += 3;    //源字符串偏移量3
   nCBIndex += 2;   //目标字符串偏移量2  因为一个中文UTF-8占3个字节,GB2312占两个字节
  }
 }
 newCharBuffer[nCBIndex] = '\0'; //结束符
 strcpy( str, newCharBuffer );
 delete newCharBuffer;  //避免内存泄漏,这是对源代码的稍许修改
 newCharBuffer = NULL;
 return str;  
}

int UtfFile::open(const char *sFileName)
{
 inf.open(sFileName);
 return inf.is_open();
}



分享到:
评论

相关推荐

    tinyxml - utf16.cpp

    以UTF=16LE编码方式保存或读取文件,可以结合博客“c++ 以UTF-16LE编码方式保存文件”查看辅助理解

    C++读取TXT文件识别特定内容修改

    由于近期需要将一份Word文档转到Markdown格式,但是文件内容较大,自动转换...程序中实现了UTF-8格式转GBK格式,使用stream对TXT进行读取并识别,获取到需要的信息后对信息进行更改,最后依据一级标题对文件进行拆分。

    C++ BUILDER6里的ini文件读写_小桥加加的IT博客-CSDN博客1

    靠谱想对作者说点什么C++ BUILDER6里的ini文件读写原创阅读数 1483收藏最后发布于2013-02-26 15:58:06点赞收藏分享发布了182

    c++ 读写txt文件和乱码问题解决

    c++实现txt文件的读写,并解决txt编码格式为UTF-8显示乱码问题。

    ASCII,UTF8编码汉字获取首字母

    utf8编码汉字获取首字母,去掉ConvertGBKToUtf8(ch);函数和引用库,ASCII编码汉字也可获取拼音首字母,第一个cpp是所有汉字可以获取首字母,第二个cpp仅针对常用汉字可用的c++获取汉字首字母

    php大文件上传示例代码-mysql-utf8

    镜像下载(JSP):cab安装包,开发文档,ASP.NET-ACCESS示例,JSP-ACCESS示例(GB2312),JSP-ACCESS示例(UTF-8),JSP-Sql2005示例(UTF-8),JSP-MySQL示例(UTF-8) 镜像下载(PHP):MySQL示例(UTF-8) 问题反馈:...

    toml++tomlplusplus-master TOML配置文件C++库

    Proper UTF-8 handling (incl. BOM) C++17 (plus some C++20 features where available, e.g. experimental support for char8_t strings) Doesn't require RTTI Works with or without exceptions Tested on Clang ...

    c++工厂模式设计的文本解析类(gbk和utf8)

    想学习工厂模式的,可以下载下来看看

    CTextFileIO读取不同编码文件

    CTextFileIO读取不同编码文件,可以判断UTF-8 NO BOM ,详情http://blog.csdn.net/akof1314/archive/2011/01/02/6113038.aspx

    C语言源代码格式化 完工 V1.04 20120226 1946.7z

    将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:UTF-8 2 UNICODE 2 ANSI。 处理文件夹。 GPX2KML 20120102 1630.7z 处理 将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:查找坐标点, ...

    C语言源代码格式化 完工 V1.05 20120229 1804.7z

    将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:UTF-8 2 UNICODE 2 ANSI。 处理文件夹。 GPX2KML 20120102 1630.7z 处理 将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:查找坐标点, ...

    C语言源代码格式化 完工 V1.08 20120801 1627.7z

    将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:UTF-8 2 UNICODE 2 ANSI。 处理文件夹。 GPX2KML 20120102 1630.7z 处理 将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:查找坐标点, ...

    C语言源代码格式化 完工 V1.09 20120821 2116.7z

    将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:查找坐标点, 然后由ANSI 2 UNICODE 2 UTF-8。 处理文件夹。 &lt;ele&gt;258.000000 &lt;time&gt;2011-03-08T08:20:31Z &lt;speed&gt;3.666667 ...

    C语言源代码格式化 完工 小文版本 V1.10 20120831 0955.zip

    将 UTF-8 格式的 字幕(或者文件) 转 ANSI 格式。 原理:查找坐标点, 然后由ANSI 2 UNICODE 2 UTF-8。 处理文件夹。 &lt;ele&gt;258.000000 &lt;time&gt;2011-03-08T08:20:31Z &lt;speed&gt;3.666667 ...

    Tinyxml 源代码(VC6 & VS2005)

    如果包含有encoding="UTF-8"的声明被读取,那么TinyXML会以UTF-8的方式来读取它。 如果读取到没有指定编码方式的声明,那么TinyXML会以UTF-8的方式来读取它。 如果包含有encoding=“其它编码”的声明被读取,那么...

    System.Data.SQLite.dll

    C#读取一些C++创建的sqlite数据库时乱码, C++保存DB是用GB2312编码的, C#调用的官方的system.data.sqlite是用的UTF-8编码的, 在读取时会乱码, 用一个GB2312编码的system.data.sqlite就行了. 可以下载sqlite源码修改...

    新版Android开发教程.rar

    支持视频格式: H.264 、流媒体、 3GPP 、 MPEG4 和 Codec 3GP ;支持音频格式: MP3 、 AAC 、 AAC+ 、 W MA 、 MPEG4 、 WAV 、 MIDI 、 REAL 、 AUDIO 和 OGG ;支持墙纸格式: JPG 、 BMP 、 PNG 和 GIF ;铃声 ...

    C/C++,C#自动识别文件编码的dll,基于uchardet

    传入文件比如txt路径,返回编码字符串比如UTF-8、UTF-16、Shift_JIS等,有BOM的稳定识别,没BOM的文本文本量越大准确率越高(默认读取2048字节进行编码判断) uchardet开源库:https://code.google.com/p/uchardet/

    易语言程序免安装版下载

    取错误文本()”返回的文本是UTF-8编码(应是GB18030编码)。 -------------------------------------------------------------------------------- 易语言5.0 相对于易语言4.x更新说明(2010/02/01):  增加...

    Qt Creator 的安装和hello world 程序+其他程序的编写--不是一般的好

    一、Qt Creator 的安装和hello world 程序的编写(原创) 1.首先到Qt 的官方网站上下载Qt Creator,这里我们下载windows 版的。 下载地址:http://qt.nokia.com/downloads 如下图我们下载:Download Qt SDK for ...

Global site tag (gtag.js) - Google Analytics