VC下Unicode编程文档
VC 中操作word
![VC 中操作word](https://img.taocdn.com/s3/m/6d921800f78a6529647d5371.png)
VC 中操作word 第一步在函数InitInstance() 中加入如下代码1.如果是word 2003if ( CoInitialize(NULL) !=0 ){AfxMessageBox("初始化COM支持库失败");exit(1);}如下图如果是word 2007 ,加入如下代码:if(TRUE != AfxOleInit()){AfxMessageBox("初始化COM支持库失败");exit(1);}如下图第二步3.打开ClassWizard—Add Class—From a type library,选择本机word8.OLB文件(最好先查找一下该文件,word2000为Word9.0LB,office2007 为MSWORD.OLB 一般在安装目录Microsoft Office\Office12 下)。
选择Application、Documents、Document、Window、View 、Range、Bookmarks、Bookmark、Fields、FieId加入新类、头文件word.h、源文件word.cpp。
如下图经过以上的添加后,在系统的存放代码文件的目录下会多出两个文件msword.cpp msword.h。
同时在VC 环境下查看类会发现多出了刚才添加的word里面的一些类,如下图所示打开对应的头文件,在文件的头部添加:#include "comdef.h"#include <AtlBase.h>#include <windows.h>第三步设计模板,准备一个word的模板,即*.dot格式的word文件,可以用word自己创建一个。
在word中用户随意设计好报表的格式,并在相应需要程序修改的位置插入书签,书签用于将程序中想要输出变量的值带入模板中,模板中的书签名字一定要与程序中的一致,笔者建议将程序中变量的名字做为书签。
VC中实现GB2312、BIG5、Unicode编码转换的方法
![VC中实现GB2312、BIG5、Unicode编码转换的方法](https://img.taocdn.com/s3/m/a1a8f6f8541810a6f524ccbff121dd36a32dc4e8.png)
VC中实现GB2312、BIG5、Unicode编码转换的⽅法本⽂主要以实例形式讨论了VC编译环境下,实现字符串和⽂件编码⽅式转换的⽅法,在linux下请使⽤Strconv来实现。
具体⽅法如下:⼀、⽂件编码格式转换//GB2312 编码⽂件转换成 Unicode:if((file_handle = fopen(filenam,"rb")) != NULL){//从GB2312源⽂件以⼆进制的⽅式读取buffernumread = fread(str_buf_pool,sizeof(char),POOL_BUFF_SIZE,file_handle);fclose(file_handle);//GB2312⽂件buffer转换成UNICODEnLen =MultiByteToWideChar(CP_ACP,0,str_buf_pool,-1,NULL,0);MultiByteToWideChar(CP_ACP,0,str_buf_pool,-1,(LPWSTR)str_unicode_buf_pool,nLen);//组装UNICODE Little Endian编码⽂件⽂件头标⽰符"0xFF 0xFE"//备注:UNICODE Big Endian编码⽂件⽂件头标⽰符"0xFF 0xFE"//Little Endian与Big Endian编码差异此处不详述unicode_little_file_header[0]=0xFF;unicode_little_file_header[1]=0xFE;//存储⽬标⽂件if((file_handle=fopen(filenewname,"wb+")) != NULL){fwrite(unicode_little_file_header,sizeof(char),2,file_handle);numwrite = fwrite(str_unicode_buf_pool,sizeof(LPWSTR),nLen,file_handle);fclose(file_handle);}}⼆、字符串编码格式转换//GB2312 转换成 Unicode:wchar_t* GB2312ToUnicode(const char* szGBString){UINT nCodePage = 936; //GB2312int nLength=MultiByteToWideChar(nCodePage,0,szGBString,-1,NULL,0);wchar_t* pBuffer = new wchar_t[nLength+1];MultiByteToWideChar(nCodePage,0,szGBString,-1,pBuffer,nLength);pBuffer[nLength]=0;return pBuffer;}//BIG5 转换成 Unicode:wchar_t* BIG5ToUnicode(const char* szBIG5String){UINT nCodePage = 950; //BIG5int nLength=MultiByteToWideChar(nCodePage,0,szBIG5String,-1,NULL,0);wchar_t* pBuffer = new wchar_t[nLength+1];MultiByteToWideChar(nCodePage,0,szBIG5String,-1,pBuffer,nLength);pBuffer[nLength]=0;return pBuffer;}//Unicode 转换成 GB2312:char* UnicodeToGB2312(const wchar_t* szUnicodeString){UINT nCodePage = 936; //GB2312int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL);char* pBuffer=new char[nLength+1];WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL);pBuffer[nLength]=0;return pBuffer;}//Unicode 转换成 BIG5:char* UnicodeToBIG5(const wchar_t* szUnicodeString){UINT nCodePage = 950; //BIG5int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL);char* pBuffer=new char[nLength+1];WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL);pBuffer[nLength]=0;return pBuffer;}//繁体中⽂BIG5 转换成简体中⽂ GB2312char* BIG5ToGB2312(const char* szBIG5String){LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);wchar_t* szUnicodeBuff = BIG5ToUnicode(szBIG5String);char* szGB2312Buff = UnicodeToGB2312(szUnicodeBuff);int nLength = LCMapString(lcid,LCMAP_SIMPLIFIED_CHINESE, szGB2312Buff,-1,NULL,0);char* pBuffer = new char[nLength + 1];LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE,szGB2312Buff,-1,pBuffer,nLength);pBuffer[nLength] = 0;delete[] szUnicodeBuff;delete[] szGB2312Buff;return pBuffer;}//简体中⽂ GB2312 转换成繁体中⽂BIG5char* GB2312ToBIG5(const char* szGBString){LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);int nLength = LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGBString,-1,NULL,0);char* pBuffer=new char[nLength+1];LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGBString,-1,pBuffer,nLength);pBuffer[nLength]=0;wchar_t* pUnicodeBuff = GB2312ToUnicode(pBuffer);char* pBIG5Buff = UnicodeToBIG5(pUnicodeBuff);delete[] pBuffer;delete[] pUnicodeBuff;return pBIG5Buff;}三、API 函数:MultiByteToWideChar参数说明第⼀个参数为代码页, ⽤ GetLocaleInfo 函数获取当前系统的代码页,936: 简体中⽂, 950: 繁体中⽂第⼆个参数为选项,⼀般⽤ 0 就可以了第三个参数为 ANSI 字符串的地址, 这个字符串是第⼀个参数指定的语⾔的 ANSI 字符串 (AnsiString)第四个参数为 ANSI 字符串的长度,如果⽤ -1, 就表⽰是⽤ 0 作为结束符的字符串第五个参数为转化⽣成的 unicode 字符串 (WideString) 的地址, 如果为 NULL, 就是代表计算⽣成的字符串的长度第六个参数为转化⽣成的 unicode 字符串缓存的容量,也就是有多少个UNICODE字符。
VC编程unicode字符集下CString转化为char数组
![VC编程unicode字符集下CString转化为char数组](https://img.taocdn.com/s3/m/9ffc1cc908a1284ac850433f.png)
int addr_len = sizeof(struct sockaddr_in);
CString strState;
//记得要用char接收数据,因为网络中传输的数据只是和编码方式无关的字节流
//所以接收到字节流后再转化为宽字符unicode编码方式用于显示和写文件
char tempSocketReceive[MAXDATALENGTH] = "";
memset(tempSocketReceive, 0, MAXDATALENGTH);//char清空;
tempSocketReceive[MAXDATALENGTH - 1] = '\0';//防止数据末尾出现烫烫烫烫,加上之后仍然出现
delete[]pwText;
int length = recvfrom(listen_socket, tempSocketReceive, MAXDATALENGTH, 0, (struct sockaddr *)&addr, &addr_len);
//判断为将多字节编码转化为宽字节编码所需要的内存空间
DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, tempSocketReceive, -1, NULL, 0);
//在堆上分配内存,申请的内存必要要释放,不然早晚会内存泄露导致程序崩溃
wchar_t *pwText;
pwText = new wchar_t[dwNum];
//将对字节转换位宽字皆unicode,转换结果保存在堆内存上,记得delete
MultiByteToWideChar(CP_ACP, 0, tempSocketReceive, -1, pwText, dwNum);
用VC++编程实现转换文本文件的字符编码
![用VC++编程实现转换文本文件的字符编码](https://img.taocdn.com/s3/m/07e96f126bd97f192279e9ef.png)
用 记 事 本 打 开 时 将 会 显 示 乱 码 , 将 设 置 改 为 C iee (R ) hn s P C 就可 正 常显 示 。 由于 U i d nc e是 国 际 通 用 的 宽 字 节 字 符 集 , o 所 以用 U i d n o e编 码 的 文 本 文 件 不 受 此 处 设 置 的影 响 , 都 可 c
件 从 一 种 字 符 编 码转 为 由另 一 种 字 符 编 码 来 存 储 .一 般 使 用 查 表 映射 的 方 式 。 在 Wi o s系列 操 作 系 统 中 ,使 用 V + 编 程 n w d C+ 时 ,这 种 字 符 映射 不 需 要 由程 序 员 来 编 写 , 可 以使 用 Widw no s
96 ( B 字符 集 ) 中 国台湾地 区使用代 码 化 大 全 的 程 序界 面
符 集 ) 程 序 启 动 时 . 自动 将 多 字 节 代 码 页设 置 为 操 作 系 统 。 默 认 的 代 码 页 。 运 行 库 中 大 多 数 多 字 节 字 符 函 数 的 行 为 , 与 当前 多 字 节 代 码 页设 置 有 关 。 比如 记 事 本 程 序 (o pdee nt a . ) e x 在 打 开 一 个 A S 编 码 的 文 本 时 ,会 根 据 操 作 系 统 的 中 的 设 NI
节 省 存 储 空 间 、提 高处 理 速 度 ,一 些 国家 和 地 区为 文 字 制 定 了 相 应 的字 符 集 ,有 的 一 种文 字 存 在 多种 字 符 集 。字 符 集 可 以 以 表 格 形 式 描 述 为 字 符 到单 字 节值 或 多 字节 值 的 映射 。 A C I S I码
VC6中设置UNICODE编程
![VC6中设置UNICODE编程](https://img.taocdn.com/s3/m/607f2df84693daef5ef73de4.png)
VC++6.0中编写Unicode编码的应用程序
VC++ 6.0支持Unicode编程,但默认的是ANSI,所以开发人员只需要稍微改变一下编写代码的习惯便可以轻松编写支持UNICODE的应用程序。
使用VC++ 6.0进行Unicode编程主要做以下几项工作:
1、为工程添加UNICODE和_UNICODE预处理选项。
具体步骤:打开[工程]->[设置…]对话框,如图1所示,在C/C++标签对话框的“预处理程序定义”中去除_MBCS,加上_UNICODE,UNICODE。
(注意中间用逗号隔开)改动后如图2:
图一
图二
在没有定义UNICODE和_UNICODE时,所有函数和类型都默认使用ANSI的版本;在定义了UNICODE和_UNICODE之后,所有的MFC类和Windows API都变成了宽字节版本了。
2、设置程序入口点
因为MFC应用程序有针对Unicode专用的程序入口点,我们要设置entry point。
否则就会出现连接错误。
设置entry point的方法是:打开[工程]->[设置…]对话框,在Link页的Output类别的Entry Point里填上wWinMainCRTStartup。
vc编码规范
![vc编码规范](https://img.taocdn.com/s3/m/a7cae353f01dc281e53af013.png)
1.1 项目取名
在VC之中,项目名为最后可执行文件名,所以项目名最好以最终的可执行文件名一致。
1.2 项目目录设置
为保证VC项目的备份方便、快捷,将所有该项目有关的文件全部放到统一的目录之下,为每个项目在该目录之下建立一个目录,项目之间的公共部分建立在public目录之下,项目所需要的基础库根据所需要的基础库数目分别建立不同的目录,项目相关的测试程序都统一放在TEST目录之下。下表显示了一个软件工程PSS系统的目录设置表:
2、 函数的输入参数不多于5个,输出参数不多于5个。
3、 对于超过3句以上的语句反复调用,应封装为函数调用。
4、 尽量避免三层以上的嵌套循环 ;尽量减少程序的 if语句;少用诸如I*=b、A=C+D*B++等语义难懂的语句。
5、 充分利用C++的思想,真正意义上地用C++语言编程;对类扩充成员函数。
// Overridables //可重载的
// Implementation //实现
每一次类都至少有一个//Implementation,在不同的位置MFC做不同的处理,在编写代码时最好
与MFC这种风格一致。
2.2 文件头部注释
文件头部注释主要是表明该文件的一些信息,其格式如下:
///////////////////////////////////////////////////////////////////
Release
VC集成环境生成的发行版本目录
Res
VC集成环境生成的资源文件目录
Include
所属mod1的头文件
Source
VC工程中各种文件
![VC工程中各种文件](https://img.taocdn.com/s3/m/b9ce40c5bb4cf7ec4afed0fa.png)
dsw, aps, clw, plg这些文件都可以删除。
只保留 H,C,CPP,DSP,RC,剩余文件去除只读属性,其余全部删除。
然后打开DSP 有提示选 YES,就可以了*.dsp(DeveloperStudio Project):是VC++的工程配置文件,比如说你的工程包含哪个文件,你的编译选项是什么等等,编译的时候是按照.dsp的配置来的。
*.dsw(DeveloperStudio Workspace):是工作区文件,用来配置工程文件的。
它可以指向一个或多个.dsp文件。
*.clw:是 ClassWizard信息文件,实际上是INI文件的格式,有兴趣可以研究一下.有时候ClassWizard出问题,手工修改CLW文件可以解决.如果此文件不存在的话,每次用ClassWizard的时候绘提示你是否重建。
*.opt:工程关于开发环境的参数文件,如工具条位置等信息。
*.aps:(AppStudio File),资源辅助文件,二进制格式,一般不用去管他。
*.rc:资源文件。
在应用程序中经常要使用一些位图、菜单之类的资源, VC中以rc为扩展名的文件称为资源文件, 其中包含了应用程序中用到的所有的windows资源, 要指出的一点是rc文件可以直接在VC集成环境中以可视化的方法进行编辑和修改。
*.plg:是编译信息文件,编译时的error和warning信息文件(实际上是一个html文件,一般用处不大),在Tools->Options里面有个选项可以控制这个文件的生成。
*.hpj:(Help Project)是生成帮助文件的工程,用microsfot Help Compiler可以处理。
*.mdp:(Microsoft DevStudio Project)是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式。
*.bsc:是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件。
Unicode下CString与char_转换
![Unicode下CString与char_转换](https://img.taocdn.com/s3/m/cb061a1352d380eb62946d68.png)
Unicode下CString与char *转换在Visual C++.NET2005中,默认的字符集形式是Unicode,但在VC6.0等工程中,默认的字符集形式是多字节字符集(MBCS:Multi-Byte Character Set),这样导致在VC6.0中非常简单实用的各类字符操作和函数在VS2005环境下运行时会报各种各样的错误,这里总结了在Visual C++.NET2005环境中Unicode字符集下CString和char *之间相互转换的几种方法,其实也就是Unicode字符集与MBCS字符集转换。
(1)、Unicode下CString转换为char *方法一:使用API:WideCharToMultiByte进行转换CString str = _T("D:\\校内项目\\QQ.bmp");//注意:以下n和len的值大小不同,n是按字符计算的,len是按字节计算的int n = str.GetLength(); // n = 14, len = 18//获取宽字节字符的大小,大小是按字节计算的int len = WideCharToMultiByte(CP_ACP,0,str,str.GetLength(),NULL,0,NULL,NULL);//为多字节字符数组申请空间,数组大小为按字节计算的宽字节字节大小char * pFileName = new char[len+1]; //以字节为单位//宽字节编码转换成多字节编码WideCharToMultiByte(CP_ACP,0,str,str.GetLength(),pFileName,len,NULL,NULL);pFileName[len+1] = '\0'; //多字节字符以'\0'结束方法二:使用函数:T2A、W2ACString str = _T("D:\\校内项目\\QQ.bmp");//声明标识符USES_CONVERSION;//调用函数,T2A和W2A均支持ATL和MFC中的字符转换char * pFileName = T2A(str);//char * pFileName = W2A(str); //也可实现转换注意:有时候可能还需要添加引用#include <afxpriv.h>(2)、Unicode下char *转换为CString方法一:使用API:MultiByteToWideChar进行转换char * pFileName = "D:\\校内项目\\QQ.bmp";//计算char *数组大小,以字节为单位,一个汉字占两个字节int charLen = strlen(pFileName);//计算多字节字符的大小,按字符计算。
VC生成word文档的部分代码的记录
![VC生成word文档的部分代码的记录](https://img.taocdn.com/s3/m/82fa5c15a76e58fafab00308.png)
protected://变量_Application wordApp;Documents wordDocs;_Document wordDoc;Selection wordSelection;Range wordRange;Tables wordTables;Table wordTable;Cell wordCell;Cells wordCells;_Font wordFont;void CAUTOY AOCE::OnCreateReport(){// CurrentCount MotherV oltageCount CommonV oltageCount PowerCount PowerFactorCount FrequencyCount// TODO:初始化WORD::CoInitialize(NULL); //初始化COM组件(必须添加,否则无法启动WORD)调用完毕后CoUninitialize();if (!wordApp.CreateDispatch(_T("Word.Application")))AfxMessageBox("Word CreateDispatch Failed!");wordApp.SetVisible(TRUE);//make visiblewordApp.Activate();//激活wordDocs=wordApp.GetDocuments();//get documents object//CComVariant tpl(_T("")),Visble,DocType(0),NewTemplate(false);wordDoc=wordDocs.Add(&tpl,&NewTemplate,&DocType,&Visble);wordSelection=wordApp.GetSelection();SYSTEMTIME sysTime;GetLocalTime(&sysTime);CString strReport;strReport.Format(" 日期: %d-%d-%d 时间: %d:%d:%d \r\n \r\n",sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute,sysTime.wSecond);wordSelection.TypeText(strReport);UpdateData();CString m_PCT;m_PCT.Format("CT变比:%f",m_CT);wordSelection.TypeText(m_PCT+" ");m_PCT.Format("PT变比:%f",m_PT);wordSelection.TypeText(m_PCT+"\r\n");/////////////////////////////////////////////////////////////////////////TODO:在WORD中插入表格if(CurrentCount) CreateDoc("遥测电流幅值检验",CurrentBuf,CurrentCount,3); //生成电流报表if(MotherVoltageCount) CreateDoc("遥测电压母线幅值检验",MotherVoltageBuf,CurrentCount,3); //生成母线电压报表if(CommonVoltageCount) CreateDoc("遥测电压普线幅值检验",CommonVoltageBuf,CurrentCount,3); //生成普线电压报表if(PowerCount) CreateDoc("遥测功率测量检验",PowerBuf,CurrentCount,2); //生成功率报表if(PowerFactorCount) CreateDoc("遥测功率因数测量检验",PowerFactorBuf,CurrentCount,1); //生成功率因数报表if(FrequencyCount) CreateDoc("遥测频率测量检验",FrequencyBuf,CurrentCount,1); //生成频率报表/////////////////////////////////////////////////////////////////////////TODO:保存WORDCComVariantFileName,FileFormat(0),LockComments(false),Password(_T("")),AddToRecentFiles(true),WritePassword(_T("")) ;CComVariantReadOnlyRecommended(false),EmbedTrueTypeFonts(false),SaveNativePictureFormat(false),SaveFormsData(fals e),SaveAsAOCELetter(false);CComVariantEncoding(false),InsertLineBreaks(false),AllowSubstitutions(false),LineEnding(false),AddBiDiMarks(false);strReport.Format("d:\\%d年%d月%d日%d时%d分%d秒报告",sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wMinute,sysTime.wSecond);FileName=strReport; //文件名wordDoc.SaveAs(&FileName,&FileFormat,&LockComments,&Password,&AddToRecentFiles,&WritePassword,&ReadOnlyRecommended,&EmbedTrueTypeFonts,&SaveNativePictureFormat,&SaveFormsData,&SaveAsAOCELetter,&Encoding,&InsertLineBreaks,&AllowSubstitutions,&LineEnding,&AddBiDiMarks);wordFont.ReleaseDispatch();wordCells.ReleaseDispatch();wordTable.ReleaseDispatch();wordTables.ReleaseDisp atch();wordRange.ReleaseDispatch();wordSelection.ReleaseDispatch();wordDoc.ReleaseDispatch();wordDocs.ReleaseDispatch();wordApp.ReleaseDis patch();::CoInitialize(NULL);}void CAUTOY AOCE::CreateCurrentDoc(){wordSelection.TypeText(" 遥测电流幅值检验报表\r\n \r\n");wordSelection.TypeText(" 日期: 2008-**-**时间: **:**\r\n \r\n");wordTables=wordDoc.GetTables();wordRange=wordSelection.GetRange();CComVariant defaultBehavior(1),AutoFitBehavior(0);wordTable=wordTables.Add(wordRange,7,7,&defaultBehavior,&AutoFitBehavior);///////////////////////////////////////////////////////////////////////UpdateData();wordCell=wordTable.Cell(1,1);wordCell.Select();wordSelection.MoveDown(&CComVariant(5),&CComVariant(1),&CComVariant(1));wordCells=wordSelection.GetCells();wordCells.Merge();wordCells.SetVerticalAlignment(1);wordSelection.TypeText("二次电流");wordCell=wordTable.Cell(1,2);wordCell.Select();wordSelection.MoveRight(&CComVariant(1),&CComVariant(2),&CComVariant(1)); //合并单元格时要使用&CComVariant(1)wordCells=wordSelection.GetCells();wordCells.Merge();wordSelection.TypeText("测控装置显示值");wordCell=wordTable.Cell(1,3);wordCell.Select();wordSelection.MoveRight(&CComVariant(1),&CComVariant(2),&CComVariant(1));wordCells=wordSelection.GetCells();wordCells.Merge();wordSelection.TypeText("操作员工作站显示值");wordSelection.MoveRight(&CComVariant(12),&CComVariant(2),&CComVariant(0));CString temp[6]={"Ia(A)","Ib(A)","Ic(A)","Ia(A)","Ib(A)","Ic(A)"};for(int i=0;i<6;i++){wordSelection.TypeText(temp[i]);wordSelection.MoveRight(&CComVariant(12),&CComVariant(1),&CComVariant(0)); //单纯右移时使用&CComVariant(12)}CString str[21]={"1.0000","x","x","x","x","x","x","5.0000","xx","xx","xx","xx","xx","xx","基本误差","xxx","xxx","xxx","xxx","xxx","xxx"};for(i=0;i<21;i++){wordSelection.TypeText(str[i]);wordSelection.MoveRight(&CComVariant(12),&CComVariant(1),&CComVariant(0));}wordSelection.TypeText("结论");wordCell=wordTable.Cell(6,2);wordCell.Select();wordSelection.MoveRight(&CComVariant(1),&CComVariant(5),&CComVariant(1));wordCells=wordSelection.GetCells();wordCells.Merge();wordSelection.TypeText("合格");wordSelection.MoveRight(&CComVariant(12),&CComVariant(1),&CComVariant(0));wordSelection.TypeText("备注");wordCell=wordTable.Cell(7,2);wordCell.Select();wordSelection.MoveRight(&CComVariant(1),&CComVariant(5),&CComVariant(1));wordCells=wordSelection.GetCells();wordCells.Merge();wordSelection.TypeText("基本误差为各测点误差的最大值;基本误差绝对值应小于0.20%");}本文来自CSDN博客,转载请标明出处:file:///E:/资料库/VC开发/word操作/VC生成word文档的部分代码%20-%20qj840828的专栏%20-%20CSDN博客.mht。
VCUTF-8转换到Unicode的函数(转)
![VCUTF-8转换到Unicode的函数(转)](https://img.taocdn.com/s3/m/74ab0036fbd6195f312b3169a45177232f60e4d9.png)
VCUTF-8转换到Unicode的函数(转)[cpp]view plaincopy1.short Utf8TextBytes (const unsigned char *mstr)2.{3.short textbytes = 0;4.if (mstr == 0)5.{ //Returns 0 if mstr contains a null string or if there is6.return 0; //no valid character in mstr.7.}8./* code checking.9.because all unicode used now is lower than 0xffff, only 1 ~3 bytes UTF-8 has means,10.the other length will not be dealed with in other functi ons */11.if (((*mstr) & 0x80) == 0)12.{13.textbytes = 1; //0xxxxxxx, normal ASCII code14.}15.else if ((((*mstr) & 0xe0) == 0xc0) && (((*(mstr + 1)) & 0xc0) == 0x80))16.{17.if (((*mstr) & 0xfe) == 0xc0) //1100,000x is illegal data,18.{19.textbytes = 0;20.}21.else22.{23.textbytes = 2; //110xxxxx 10xxxxxx24.}25.}26.else if ((((*mstr) & 0xf0) == 0xe0) && (((*(mstr + 1)) & 0xc0) == 0x80) && (((*(mstr + 2)) & 0xc0) == 0x80))27.{28.if ((*mstr == (char) 0xe0) && (((*(mstr + 1)) & 0xe0) = = 0x80)) //1110,0000,100x,xxxx is illegal data29.{30.textbytes = 0;31.}32.else33.{34.textbytes = 3; //1110xxxx 10xxxxxx 10xxxxxx35.}36.}37.else if ((((*mstr) & 0xf8) == 0xf0) && (((*(mstr + 1)) & 0xc0) == 0x80) && (((*(mstr + 2)) & 0xc0) == 0x80)38.&& (((*(mstr + 3)) & 0xc0) == 0x80))39.{40.if (((*mstr) == (char) 0xf0) && (((*(mstr + 1)) & 0xf0) = = 0x80)) // 1111,0000,1000,xxxx is illegal data41.{42.textbytes = 0;43.}44.else45.{46.textbytes = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxx xxx47.}48.}49.else if ((((*mstr) & 0xfc) == 0xf8) && (((*(mstr + 1)) & 0xc0) == 0x80) &&50.(((*(mstr + 2)) & 0xc0) == 0x80) && (((*(mstr + 3)) & 0 xc0) == 0x80) && (((*(mstr + 4)) & 0xc0) == 0x80))51.{52.if ((*mstr == (char) 0xf8) && (((*(mstr + 1)) & 0xf8) = = 0x80)) //1111,1000,1000,0xxx is illegal data53.{54.textbytes = 0;55.}56.else57.{58.textbytes = 5; //111110xx 10xxxxxx 10xxxxxx 10xxx xxx 10xxxxxx59.}60.}61.else if ((((*mstr) & 0xfe) == 0xfc) && (((*(mstr + 1)) & 0xc0) == 0x80) &&62.(((*(mstr + 2)) & 0xc0) == 0x80) && (((*(mstr + 3)) & 0 xc0) == 0x80) && (((*(mstr + 4)) & 0xc0) == 0x80) &&63.(((*(mstr + 5)) & 0xc0) == 0x80))64.{65.if ((*mstr == (char) 0xfc) && (((*(mstr + 1)) & 0xfc) == 0x80)) //1111,1100,1000,00xx is illegal data66.{67.textbytes = 0;68.}69.else70.{71.textbytes = 6; //1111110x 10xxxxxx 10xxxxxx 10xxx xxx 10xxxxxx 10xxxxxx72.}73.}74.else75.{76.textbytes = 0; //illegal formal, return 077.}78.79.return textbytes;80.}utf8Str --UTF8 source stringutf8strlen --max utf8 lengthunStr -- Unicode Str destunMaxlen --Unicode 最大个数return : --实际转化的长度short FromUTF8T oUnicode (unsigned char *utf8Str, short utf8StrLen, WORD * unStr, unsigned short unMaxLen) [cpp]view plaincopy1.{2.short zen_han, len_dest;3.unsigned char *p_src;4.unsigned char utf8_len = 0;5.len_dest = 0;6.p_src = (unsigned char *) (utf8Str);7.8./* limit the total bytes of the *mstr */9.if (utf8StrLen <= 0)11.return (0);12.}13.14./* converting at here utf8_len <= utf8StrLen 改为 utf8_len < utf8StrLen*/15.for (; (*p_src != 0x00) && (len_dest <= unMaxLen - 1) && (utf8_len < utf8StrLen);)16.{17.zen_han = Utf8TextBytes ((const unsigned char *) p_src);18.if (zen_han == 1) //ASCII, just add 0x00 at beginni ng19.{20.(*unStr) = *(p_src);21.unStr++;22.p_src++;23.utf8_len++;24.len_dest += 1;25.}26.else if (zen_han == 2)27.{28.*unStr = (((((*p_src) >> 2) & (unsigned char) 0x07)) & 0x00ff) << 8;29.*unStr |= ((((*p_src) << 6) | ((*(p_src + 1)) & (unsigned char) 0x3f))) & 0x00ff;30.unStr++;31.p_src += 2;32.utf8_len += 2;33.len_dest += 1;35.}36.else if (zen_han == 3)37.{38.*(unStr) = ((((*(p_src)) << 4) | (((*(p_src + 1)) >> 2) & 0 x0f)) & 0x00ff) << 8;39.40.*unStr |= ((((*(p_src + 1)) << 6) | ((*(p_src + 2)) & (unsi gned char) 0x3f))) & 0x00ff;41.unStr++;42.p_src += 3;43.utf8_len += 3;44.len_dest += 1;45.}46.else if (zen_han == 4) //47.{48.*unStr = (*(p_src)) & 0x7;49.for (int i=1; i<4;i++)50.{51.*unStr <<= 6; // 左移6位后与后续字节的有效位值"位或"赋值52.*unStr = *unStr | ((*(p_src + i)) & 0x3f);//先与后或53.}54.unStr++;55.p_src += 4;56.utf8_len += 4;57.len_dest += 1;58.}59.else if (zen_han == 5) //60.{61.*unStr = (*(p_src)) & 0x3;62.for (int i=1; i<5;i++)63.{64.*unStr <<= 6; // 左移6位后与后续字节的有效位值"位或"赋值65.*unStr = *unStr | ((*(p_src + i)) & 0x3f);//先与后或66.}67.unStr++;68.p_src += 5;69.utf8_len += 5;70.len_dest += 1;71.}72.else if (zen_han == 6) //73.{74.*unStr = (*(p_src)) & 0x1;75.for (int i=1; i<6;i++)76.{77.*unStr <<= 6; // 左移6位后与后续字节的有效位值"位或"赋值78.*unStr = *unStr | ((*(p_src + i)) & 0x3f);//先与后或79.}80.unStr++;81.p_src += 6;82.utf8_len += 6;83.len_dest += 1;84.}85.else //treated as illegal character, search the next character86.{87.p_src++;88.utf8_len++;89.}90.}91.*(unStr) = 0x0000;92.return (len_dest);93.94.}。
C读写Unicode编码文件
![C读写Unicode编码文件](https://img.taocdn.com/s3/m/0fae0fb7c77da26925c5b077.png)
#include <stdio.h>#include <stdlib.h>#include <LOCALE.H>#define BOM 65279 /* Unicode文件BOM头*/#define TRM 12290 /* 句号,即结束符*//************************************************************功能:从C:\before.txt中读取内容,以。
为结束符,遇结束符换行,后将结果存入C:\after.txt中************************************************************/int main(){setlocale(LC_ALL, ""); /* 配置地域的信息,为了使wchar_t输出可显示*/wchar_t lcv_OprWChar; /* 用以操作的字符*/FILE *lfv_GetFile, *lfv_PutFile;wchar_t *lcv_GetFilePath = L"C:\\before.txt", *lcv_PutFilePath = L"C:\\after.txt";lfv_GetFile=_wfopen(lcv_GetFilePath,L"rb"); /* 以二进制方式只读*/lfv_PutFile=_wfopen(lcv_PutFilePath,L"wb"); /* 以二进制方式只写*/if (NULL == lfv_GetFile || NULL == lfv_PutFile) /* 当文件不存在,或者打开失败时*/ {printf("文件获取错误错误!");exit(1); /* 退出程序,需要引入stdlib.h头文件*/} /* if (NULL == lfv_OprFile || NULL == lfv_PutFile)判断结束*/while ((lcv_OprWChar = getwc(lfv_GetFile)) != WEOF){if (lcv_OprWChar != BOM) /* 当读取的是Bom头时,跳过*/{putwchar(lcv_OprWChar);} /* if (lcv_GetWChar == BOM)判断结束*/putwc(lcv_OprWChar, lfv_PutFile);if (lcv_OprWChar == TRM) /* 当读取的是句号结束符时,加换行\r\n */{putwc((wchar_t)13, lfv_PutFile); /* \r */putwc((wchar_t)10, lfv_PutFile); /* \n */} /* if (lcv_GetWChar == TRM)判断结束*/} /* while ((lcv_GetWChar...WEOF)循环结束*/fclose(lfv_PutFile);fclose(lfv_PutFile);return 0;}。
C++11与Unicode及使用标准库进行UTF
![C++11与Unicode及使用标准库进行UTF](https://img.taocdn.com/s3/m/bf590e90a1116c175f0e7cd184254b35eefd1af1.png)
C++11与Unicode及使用标准库进行UTF文章目录1.1. Unicode2.2. Unicode的编码方式1. 2.1. UTF-8(8-bit Unicode Transformation Format)2. 2.2. UTF-16(16-bit Unicode Transformation Format)1. 2.2.1. 基本多语言平面(码位范围U+0000-U+FFFF)2. 2.2.2. 辅助平面(码位范围U+10000-U+10FFFF)3. 2.3. UCS2(2-byte Universal Character Set)4. 2.4. UCS4(4-byte Universal Character Set)/UTF-32(32-bit Unicode Transformation Format)3.3. C++11对Unicode的支持1. 3.1. USL(Unicode String Literals)2. 3.2. 使用C++11标准库进行编码转换1. 3.2.1. UTF-8与UTF-16编码转换2. 3.2.2. UTF-8与UCS2编码转换及UTF-8与UCS4编码转换3. 3.2.3. UTF-16与UCS2编码转换及UTF-16与UCS4编码转换4. 3.2.4. BOM(Byte Order Mark)UnicodeUnicode是计算机领域的一项行业标准,它对世界上绝大部分的文字的进行整理和统一编码,Unicode的编码空间可以划分为17个平面(plane),每个平面包含2的16次方(65536)个码位。
17个平面的码位可表示为从U+0000到U+10FFFF,共计1114112个码位,第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0)。
其他平面称为辅助平面(SupplementaryPlanes)。
Unicode转为GBK的C语言程序
![Unicode转为GBK的C语言程序](https://img.taocdn.com/s3/m/653e2e47f11dc281e53a580216fc700abb6852ac.png)
Unicode转为GBK的C语⾔程序#include#define uint unsigned int#define uchar unsigned charuint GBcode=0;xdata uchar a_dot[192];uchar UCSadd1,UCSadd2,UCSadd3;uchar ADH,ADL,ADLL;uchar i,num,k,temp1;bit done=0;/////SPI引脚连接//////sbit CS=P1^7;sbit MOSI=P0^2;sbit MISO=P0^1;sbit SCK=P0^0;/////LED引脚连接//////sbit CLK=P1^0; // 时钟信号sbit STB=P1^1; // 锁存信号,上升沿sbit R=P1^2; //数据输⼊端⼝sbit OE=P1^3; // 使能信号,⾼电平有效void Oscillator_Init();//f410初始化void SPI_Init(); //SPI初始化void int_T2(); //T2初始化void delay();void save(uchar x); //存储点阵代码void display(); //LED显⽰void WriteByte(uchar dat); //写⼀个字节的数据void LED(uint GB_code);void UnicodeToGB2312(uchar jj,uchar *ss);void main(){uchar q;uchar Unicode[]={0x4f,0x60};CS=1;Oscillator_Init(); //硬件初始SPI_Init(); //SPI初始化for(q=0;q<192;q++) a_dot[q]=0;UnicodeToGB2312(0,Unicode);//Unicode转GB2312LED(GBcode);while(1);}void Oscillator_Init(){PCA0MD&=~0x40; ///关看门狗PCA0MD=0x00;OSCICN=0x87;///8分频P0MDOUT=0x1D; ///MOSI CLK设置为推挽输出; MISO设为漏极输出P1MDOUT =0x7f;//p1设置为开漏P2MDOUT =0xff;XBR0=0x03;////开 SPI 端⼝连接XBR1=0x40; /////开交叉开关// IP |= 0x10; // Make UART high priority// IE=0xb0; // Enable UART0 interrupts}void SPI_Init(){SPI0CFG=0x77; //上升沿时钟,⼯作在主⽅式;SPI0CKR=0xdf; //SPI0时钟频率;SPI0CN=0x03; //SPI使能}////////////T2初始化/////////void int_T2(){ CKCON=0x00; //T0频率为f/12// EA=1;TMR2RLH=0xf4;TMR2RLL=0xac;// ET2=1;}/********************led写数据******************************/ void WriteByte(uchar dat) //写⼀个字节的数据{uchar i11;for(i11=0;i11<8;i11++) //循环8次把编码传给锁存器{dat=dat<<1; //移⼀位,取出该字节的最低位R=CY; //将该字节的最低位传给RCLK=0; //将数据移⼊595,上升沿CLK=1;}}/*********************LED扫描数据**************************/ void display(){uchar temp2,a;temp2=i;for(a=0;a<4;a++ ){WriteByte(a_dot[num+i+k]); //送出四个字节,给四个595 i-=8;}i=temp2+1;for(a=0;a<4;a++ ){WriteByte(a_dot[num+i+k]); //送出四个字节,给应四个595 i-=8;}}void delay(){unsigned int Z0,Z1;for(Z0=0;Z0<2;Z0++){for (Z1=0;Z1<3;Z1++);}}void save(uchar x){uchar i0,j0,f0;for(j0=0;j0<32;j0++){for(i0=0;i0<8;i0++){f0=f0<<1;SCK = 0;SCK = 1;if(MISO) f0++;}a_dot[j0+x*64]=f0;}}void UnicodeToGB2312(uchar jj,uchar *ss){uint code1;unsigned long ptr=0;uchar result=0,result1=0;uchar GB2312Code[2];unsigned long UToGb2312Buff =0x67d70;uint h;uchar s0,s1,dat0;code1=(uint)(ss[jj]*256+ss[jj+1]);if(code1<0x20) result=1;else if(code1<0xa0) result1=1;else if(code1<=0xf7) h=code1-160;else if(code1<0x2c7) result=1;else if(code1<=0x2c9) h=code1-160-463;else if(code1<0x2010) result=1;else if(code1<=0x2312) h=code1-160-463-7494;else if(code1<0x2460) result=1;else if(code1<=0x2642) h=code1-160-463-7494-333;else if(code1<0x3000) result=1;else if(code1<=0x3017) h=code1-160-463-7494-333-2493;else if(code1<0x3220) result=1;else if(code1<=0x3229) h=code1-160-463-7494-333-2493-520;else if(code1<0x4e00) result=1;else if(code1<=0x9b54) h=code1-160-463-7494-333-2493-520-7126;else if(code1<0x9c7c) result=1;else if(code1<=0x9ce2) h=code1-160-463-7494-333-2493-520-7126-295;else if(code1<0x9e1f) result=1;else if(code1<=0x9fa0) h=code1-160-463-7494-333-2493-520-7126-295-316;else if(code1<0xe76c) result=1;else if(code1<=0xe774) h=code1-160-463-7494-333-2493-520-7126-295-316-18379;else if(code1<0xff00) result=1;else if(code1<=0xff5f) h=code1-160-463-7494-333-2493-520-7126-295-316-18379-6027; else if(code1<0xffe0) result=1;else if(code1<=0xffe5) h=code1-160-463-7494-333-2493-520-7126-295-316-18379-6027-128; else result=1;if(result1==0){if(result==0){ptr = UToGb2312Buff + (h<<1);}{ptr=0x0000a1a1;}UCSadd1=ptr/65536;UCSadd2=ptr/256;UCSadd3=ptr%256;CS=1;CS=0;SPI0DAT=0x03;while (!SPIF);SPIF=0;SPI0DAT=UCSadd1;while (!SPIF);SPIF=0;SPI0DAT=UCSadd2;while (!SPIF);SPIF=0;SPI0DAT=UCSadd3;while (!SPIF);SPIF=0;XBR0=0x01;////关 SPI 端⼝连接for(s0=0;s0<2;s0++){for(s1=0;s1<8;s1++){dat0=dat0<<1;SCK = 0;SCK = 1;if(MISO) dat0++;}GB2312Code[s0]=dat0;}CS=1;XBR0=0x03;////开 SPI 端⼝连接GBcode=(uint)(GB2312Code[0]*256+GB2312Code[1]);}elseGBcode=code1+0xa380;// return (GBcode);}void LED(uint GB_code){unsigned long Address=0;uchar MSB,LSB;MSB=GB_code/256;LSB=GB_code%256;if(MSB >=0xA1 && MSB <= 0xA3 && LSB >=0xA1)Address =(unsigned long)( (MSB - 0xA1) * 94 + (LSB - 0xA1))*32; else if(MSB >=0xA4 && MSB <= 0xa8 && LSB >=0xA1)Address = 0;else if(MSB ==0xA9 && LSB >=0xA1)Address =(unsigned long)(282 + (LSB - 0xA1 ))*32;else if(MSB >=0xB0 && MSB <= 0xF7 && LSB >=0xA1)Address =(unsigned long)((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32; ADH=Address/0x10000;ADL=Address%0x10000/256;ADLL=Address%256;delay(); //////延时确保正确写⼊数据CS=0;SPI0DAT=0x03;while (!SPIF);SPIF=0;SPI0DAT=ADH;while (!SPIF);SPIF=0;SPI0DAT=ADL;while (!SPIF);SPIF=0;SPI0DAT=ADLL;while (!SPIF);SPIF=0;XBR0=0x01;////关 SPI 端⼝连接save(0);CS=1;XBR0=0x03;////关 SPI 端⼝连接}。
VC的Unicode编程
![VC的Unicode编程](https://img.taocdn.com/s3/m/1d444d260812a21614791711cc7931b765ce7b69.png)
VC 的Unicode编程本文来自:一、什么是Unicode先从ASCII说起,ASCII是用来表示英文字符的一种编码规范。
每个ASCII 字符占用1个字节,因此,ASCII编码可以表示的最大字符数是255(00H-FFH)。
其实,英文字符并没有那么多,一般只用前128个(00H-7FH,最高位为0),其中包括了控制字符、数字、大小写字母和其它一些符号。
而最高位为1的另128个字符(80H-FFH)被称为"扩展ASCII",一般用来存放英文的制表符、部分音标字符等等的一些其它符号。
这种字符编码规则显然用来处理英文没有什么问题。
但是面对中文、阿拉伯文等复杂的文字,255个字符显然不够用。
于是,各个国家纷纷制定了自己的文字编码规范,其中中文的文字编码规范叫做"GB2312-80",它是和ASCII兼容的一种编码规范,其实就是利用扩展ASCII没有真正标准化这一点,把一个中文字符用两个扩展ASCII字符来表示,以区分ASCII码部分。
但是这个方法有问题,最大的问题就是中文的文字编码和扩展ASCII码有重叠。
而很多软件利用扩展ASCII码的英文制表符来画表格,这样的软件用到中文系统中,这些表格就会被误认作中文字符,出现乱码。
另外,由于各国和各地区都有自己的文字编码规则,它们互相冲突,这给各国和各地区交换信息带来了很大的麻烦。
要真正解决这个问题,不能从扩展ASCII的角度入手,而必须有一个全新的编码系统,这个系统要可以将中文、法文、德文…等等所有的文字统一起来考虑,为每一个文字都分配一个单独的编码。
于是,Unicode诞生了。
Unicode也是一种字符编码方法,它占用两个字节(0000H-FFFFH),容纳65536个字符,这完全可以容纳全世界所有语言文字的编码。
在Unicode里,所有的字符被一视同仁,汉字不再使用"两个扩展ASCII",而是使用"1个Unicode",也就是说,所有的文字都按一个字符来处理,它们都有一个唯一的Unicode码。
C语言:Unicode字符集
![C语言:Unicode字符集](https://img.taocdn.com/s3/m/96409bc332d4b14e852458fb770bf78a65293a88.png)
C语⾔:Unicode字符集Unicode 也称为统⼀码、万国码;看名字就知道,Unicode 希望统⼀所有国家的字符编码。
Unicode 于 1994 年正式公布第⼀个版本,现在的规模可以容纳 100 多万个符号,是⼀个很⼤的集合。
有兴趣的读取可以转到查看 Unicode 包含的所有字符,以及各个国家的字符是如何分布的。
Windows、Linux、Mac OS 等常见操作系统都已经从底层(内核层⾯)开始⽀持 Unicode,⼤部分的⽹页和软件也使⽤Unicode,Unicode 是⼤势所趋。
不过由于历史原因,⽬前的计算机仍然安装了 ASCII 编码以及 GB2312、GBK、Big5、Shift-JIS 等地区编码,以⽀持不使⽤ Unicode 的软件或者⽂档。
内核在处理字符时,⼀般会将地区编码先转换为 Unicode,再进⾏下⼀步处理。
Unicode 字符集是如何存储的本节我们多次说 Unicode 是⼀套字符集,⽽不是⼀套字符编码,它们之间究竟有什么区别呢?严格来说,字符集和字符编码不是⼀个概念:字符集定义了字符和⼆进制的对应关系,为每个字符分配了唯⼀的编号。
可以将字符集理解成⼀个很⼤的表格,它列出了所有字符和⼆进制的对应关系,计算机显⽰⽂字或者存储⽂字,就是⼀个查表的过程。
⽽字符编码规定了如何将字符的编号存储到计算机中。
如果使⽤了类似 GB2312 和 GBK 的变长存储⽅案(不同的字符占⽤的字节数不⼀样),那么为了区分⼀个字符到底使⽤了⼏个字节,就不能将字符的编号直接存储到计算机中,字符编号在存储之前必须要经过转换,在读取时还要再逆向转换⼀次,这套转换⽅案就叫做字符编码。
有的字符集在制定时就考虑到了编码的问题,是和编码结合在⼀起的,例如 ASCII、GB2312、GBK、BIG5 等,所以⽆论称作字符集还是字符编码都⽆所谓,也不好区分两者的概念。
⽽有的字符集只管制定字符的编号,⾄于怎么存储,那是字符编码的事情,Unicode 就是⼀个典型的例⼦,它只是定义了全球⽂字的唯⼀编号,我们还需要 UTF-8、UTF-16、UTF-32 这⼏种编码⽅案将 Unicode 存储到计算机中。
VC++源文件编码
![VC++源文件编码](https://img.taocdn.com/s3/m/13534a1a78563c1ec5da50e2524de518964bd3a8.png)
VC++源⽂件编码⽬录第1章源代码⽂件VC++源代码⽂件(*.h;*.hpp;*.c;*.cxx;*.cpp;*.inl……),在VC++6.0时都是ANSI编码,从VC++2002开始逐步⽀持Unicode编码。
在不同的⽂件编码下,VC++编译器对字符串的编译处理是不同的。
本⽂对此进⾏详细说明。
1.1 研究思路如下表所⽰,⽣成四个源代码⽂件://ANSI936.cpp 保存为 ANSI 编码(代码页为 936 GBK)static char* s = "936-ssssss-A";static wchar_t* w = L"936-wwwwww-A";//UTF8.cpp 保存为 UTF-8 编码(有BOM)static char* s = "utf8-ssssss-A®";static wchar_t* w = L"utf8-wwwwww-A®";//UTF16BE.cpp 保存为 UTF-16编码(⾼位字节在前,有BOM)static char* s = "utf16BE-ssssss-A®";static wchar_t* w = L"utf16BE-wwwwww-A®";//UTF16LE.cpp 保存为 UTF-16编码(低位字节在前,有BOM)static char* s = "utf16LE-ssssss-A®";static wchar_t* w = L"utf16LE-wwwwww-A®";使⽤VC++打开编译后⽣成的exe⽂件。
如下图所⽰,请单击"Open"按钮的右端,弹出菜单中,请单击【Open With...】菜单项图1.1显⽰如下对话框:图1.2上图中,选择"Binary Editor"(⼆进制编辑器),然后单击OK按钮。
VC+ANSI环境下按行读取ANSI、UNICODE+、UNICODE+big+endian、UTF-8四种文本文件
![VC+ANSI环境下按行读取ANSI、UNICODE+、UNICODE+big+endian、UTF-8四种文本文件](https://img.taocdn.com/s3/m/a0325e2ea5e9856a56126013.png)
2012-04-19 20:07112人阅读评论(0)收藏举报VC ANSI环境下按行读取ANSI、UNICODE 、UNICODE big endian、UTF-8四种文本文件1.问题提出MFC提供的文件类CStdioFile,其中一个函数ReadString实现了文件的按行读取,但是不能满足不同类型的文本文件的按行读取,为了解决这一问题,笔者初步研究了一些编码知识,参考了网上的一些资料,实现了CStdioFile类的扩展类CStdioFileEx,完成了常见文本文件的按行读取(注明:不包括DOC、PDF等其他形式的文档).在此对网上分享编码经验的网友表示感谢,同时由于我编写的类还未经过严格测试,如有错误或方法过于复杂敬请各位指正。
2.问题解决(1)四种常见文本文件编码方式研究ANSI、UNICODE 、UNICODE big endian、UTF-8四种格式编码存在差别,简要介绍如下:ANSI编码:无文件头(文件编码开头标志性字节)ANSI编码字母数字占一个字节,汉字占两个字节,回车换行符单字节十六进制表示为0d 0aUNICODE编码:文件头,十六进制表示为FF FE每一个字符都用两个字节编码回车换行符双字节000d 000aUnicode big endian编码:文件头十六进制表示为FE FF ,后面编码是把字符的高位放在前面,低位放在后面,正好和Unicode编码颠倒。
回车换行符,双字节,十六进制表示为0d00 0a00UTF-8 编码:文件头,十六进制表示为EF BB BF。
UTF-8是Unicode的一种变长字符编码,数字、字母、回车、换行都用一个字节表示,汉字占3个字节.回车换行符,单字节,十六进制表示为0d 0a以中文"你好"二字为例,各种类型的编码对应的十六进制格式(可由EditPlus查看)如下图所示:由此可见上述的探讨是正确的。
(2)按行读取上述四种格式文本文件的解决方案针对不同文件编码的特点,通过先检测文件头判断文件编码类型,然后根据文件类型分别调用不同的读取函数实现文件的按行读取。
VC下UNICOD和UTF8相互转换
![VC下UNICOD和UTF8相互转换](https://img.taocdn.com/s3/m/ed077248852458fb770b56df.png)
Vc下unicode和UTF8相互转换在vc下使用SQLite数据库时,由于SQL语句使用utf8 编码,而CString 是unicode编码。
一, utf8 转UnicodeCString UTF8ToUnicode(char* UTF8){DWORD dwUnicodeLen; //转换后Unicode的长度TCHAR *pwText; //保存Unicode的指针CString strUnicode; //返回值//获得转换后的长度,并分配内存dwUnicodeLen = MultiByteToWideChar(CP_UTF8,0,UTF8,-1,NULL,0); pwText = new TCHAR[dwUnicodeLen];if (!pwText){return strUnicode;}//转为UnicodeMultiByteToWideChar(CP_UTF8,0,UTF8,-1,pwText,dwUnicodeLen);//转为CStringstrUnicode.Format(_T("%s"),pwText);//清除内存delete []pwText;//返回转换好的Unicode字串}二, Unicode转utf8size_t CDGQDialog::g_f_wctou8(char * dest_str, const wchar_t src_wchar){int count_bytes = 0;wchar_t byte_one = 0, byte_other = 0x3f; // 用于位与运算以提取位值0x3f--->00111111 unsigned char utf_one = 0, utf_other = 0x80; // 用于"位或"置标UTF-8编码0x80--->1000000 wchar_t tmp_wchar =L'0'; // 用于宽字符位置析取和位移(右移位)unsigned char tmp_char =L'0';if (!src_wchar)//return (size_t)-1;for (;;) // 检测字节序列长度{if (src_wchar <= 0x7f){ // <=01111111count_bytes = 1; // ASCII字符: 0xxxxxxx( ~ 01111111)byte_one = 0x7f; // 用于位与运算, 提取有效位值, 下同utf_one = 0x0;break;}if ( (src_wchar > 0x7f) && (src_wchar <= 0x7ff) ){ // <=0111,11111111count_bytes = 2; // 110xxxxx 10xxxxxx[1](最多个位, 简写为*1)byte_one = 0x1f; // 00011111, 下类推(1位的数量递减)break;}if ( (src_wchar > 0x7ff) && (src_wchar <= 0xffff) ){ //0111,11111111<=11111111,11111111 count_bytes = 3; // 1110xxxx 10xxxxxx[2](MaxBits: 16*1)byte_one = 0xf; // 00001111utf_one = 0xe0; // 11100000break;}if ( (src_wchar > 0xffff) && (src_wchar <= 0x1fffff) ){ //对UCS-4的支持..count_bytes = 4; // 11110xxx 10xxxxxx[3](MaxBits: 21*1)byte_one = 0x7; // 00000111utf_one = 0xf0; // 11110000break;}if ( (src_wchar > 0x1fffff) && (src_wchar <= 0x3ffffff) ){count_bytes = 5; // 111110xx 10xxxxxx[4](MaxBits: 26*1)byte_one = 0x3; // 00000011utf_one = 0xf8; // 11111000break;}if ( (src_wchar > 0x3ffffff) && (src_wchar <= 0x7fffffff) ){count_bytes = 6; // 1111110x 10xxxxxx[5](MaxBits: 31*1)utf_one = 0xfc; // 11111100break;}return (size_t)-1; // 以上皆不满足则为非法序列}// 以下几行析取宽字节中的相应位, 并分组为UTF-8编码的各个字节tmp_wchar = src_wchar;for (int i = count_bytes; i > 1; i--){ // 一个宽字符的多字节降序赋值tmp_char = (unsigned char)(tmp_wchar & byte_other);///后位与byte_other 00111111 dest_str[i - 1] = (tmp_char | utf_other);/// 在前面加----跟或tmp_wchar >>= 6;//右移位}//这个时候i=1//对UTF-8第一个字节位处理,//第一个字节的开头"1"的数目就是整个串中字节的数目tmp_char = (unsigned char)(tmp_wchar & byte_one);//根据上面附值得来,有效位个数dest_str[0] = (tmp_char | utf_one);//根据上面附值得来1的个数// 位值析取分组__End!return count_bytes;}int CDGQDialog::g_f_wcs_to_pchar(CString& wstr,char * p)wchar_t wc=L'1';char c[10]="1";//申请一个缓存size_t r=0; //size_t unsigned integer Result of sizeof operator int i=0;int j=0;for(i=0;i<wstr.GetLength();i++){wc=wstr.GetAt(i);//得到一个宽字符r=g_f_wctou8(c,wc);//将一个宽字符按UTF-8格式转换到p地址if(r==-1)//出错判断AfxMessageBox(_T("wcs_to_pchar error"));p[j]=c[0];//第一个值附给pj++;if(r>1){for(size_t x=1;x<r;x++){p[j]=c[x];j++;}}}return 1;}三.转换实例void CMytestDlg::OnBnClickedButton2(){// TODO: 在此添加控件通知处理程序代码CString ccId=L"2007071王";CString sql;char mySql[100];memset(mySql,0,sizeof(mySql));sql.Format(L"select cxrq,cxdw,dxrq,dxdw,fxrq,fxdw,cx,flx from j_clxx where trainnum_info_id ='%s'",ccId); //wchar_t sql=L'你';g_f_wcs_to_pchar(sql,mySql);CString sql1 =UTF8ToUnicode(mySql);MessageBox(sql);//g_f_wctou8(mySql,sql);// CString str_temp;// for (int i=90;i<strlen(mySql);i++)// {// str_temp.Format(L"%c",mySql[i]);// MessageBox(str_temp);// }。
UNICODE编程资料
![UNICODE编程资料](https://img.taocdn.com/s3/m/d11fddc1d5bbfd0a795673de.png)
UNICODE编程资料说明1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数?可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。
调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。
2. 如何对DBCS(双字节字符集)字符串进行操作?函数描述PTSTR CharNext ( LPCTSTR ); 返回字符串中下一个字符的地址PTSTR CharPrev ( LPCTSTR, LPCTSTR );返回字符串中上一个字符的地址BOOL IsDBCSLeadByte( BYTE );如果该字节是DBCS字符的第一个字节,则返回非0值3. 为什么要使用Unicode?(1)可以很容易地在不同语言之间进行数据交换。
(2)使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。
(3)提高应用程序的运行效率。
Windows 2000是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那么系统首先要将字符串转换成 Unicode,然后将Unicode字符串传递给操作系统。
如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给你的应用程序。
进行这些字符串的转换需要占用系统的时间和内存。
通过从头开始用Unicode来开发应用程序,就能够使你的应用程序更加有效地运行。
Windows CE 本身就是使用Unicode的一种操作系统,完全不支持ANSI Windows函数Windows 98 只支持ANSI,只能为ANSI开发应用程序。
Microsoft公司将COM从16位Windows转换成Win32时,公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。
4. 如何编写Unicode源代码?Microsoft 公司为Unicode设计了WindowsAPI,这样,可以尽量减少代码的影响。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 Unicode编程1.1 VC++下的Unicode编程ASCII是用来表示英文字符的一种编码规范。
每个ASCII字符占用1个字节,因此,ASCII编码可以表示的最大字符数是255(00H-FFH)。
其实,英文字符并没有那么多,一般只用前128个(00H-7FH,即0x0000 0000-0x0111 1111,最高位为0),其中包括了控制字符、数字、大小写字母和其它一些符号。
而另128个字符(80H-FFH,即0x1000 0000-0x1111 1111,最高位为1)被称为“扩展ASCII”,一般用来存放英文的制表符、部分音标字符等等的一些其它符号。
中文编码规范“GB2312-80”,其实就是利用把一个中文字符用两个扩展ASCII字符来表示,以区分ASCII码部分。
这个方法有问题,最大的问题就是中文的文字编码和扩展ASCII码有重叠。
而很多软件利用扩展ASCII码的英文制表符来画表格,这样的软件用到中文系统中,这些表格就会被误认作中文字符,出现乱码。
要真正解决这个问题,不能从扩展ASCII的角度入手,而必须有一个全新的编码系统,这个系统要可以为每一种文字的每个字符均分配一个单独的编码,Unicode为此诞生!Unicode也是一种字符编码方法,它占用两个字节(0000H—FFFFH),容纳65536个字符,这完全可以容纳全世界所有语言文字的编码。
在Unicode里,所有的字符被一视同仁,汉字不再使用“两个扩展ASCII”,而是所有的文字都按一个字符来处理,它们都有一个唯一的Unicode码。
使用Unicode编码可以使您的工程同时支持多种语言,使您的工程国际化。
Windows NT是使用Unicode进行开发的,整个系统都是基于Unicode的。
如果调用一个API函数并给它传递一个ANSI(ASCII字符集以及由此派生并兼容的字符集,如:GB2312,通常称为ANSI字符集)字符串,那么系统首先要将字符串转换成Unicode,然后将Unicode字符串传递给操作系统。
进行这些字符串的转换需要占用系统的时间和内存。
如果用Unicode来开发应用程序,就能够使您的应用程序更加有效地运行。
下面例举几个字符的编码以简单演示ANSI和Unicode的区别:(注意:中文对宽字符的支持其实是ANSI C标准的一部分,用以支持多字节表示一个字符。
宽字符和Unicode并不完全等同,Unicode只是宽字符的一种编码方式。
(1)宽字符的定义在ANSI中,一个字符(char)的长度为一个字节(Byte)。
使用Unicode 时,一个字符占据一个字(2 Bytes),C++在wchar.h头文件中定义了最基本的宽字符类型wchar_t:typedef unsigned short wchar_t;// 所谓的宽字符就是无符号短整数(2)常量宽字符串对C++程序员而言,构造字符串常量是一项经常性的工作。
那么,如何构造宽字符字符串常量呢?很简单,只要在字符串常量前加上一个大写的L就可以了,比如:wchar_t *str1 = L" Hello";这个L非常重要,只有带上它,编译器才知道你要将字符串存成一个字符一个字(即一个字符两字节)。
还要注意,在L和字符串之间不能有空格。
(3)宽字符串库函数为了操作宽字符串,C++专门定义了一套函数,比如求宽字符串长度的函数是:size_t __cdel wchlen(const wchar_t*);为什么要专门定义这些函数呢?最根本的原因是,ANSI下的字符串都是以’’来标识字符串尾的(Unicode字符串以“”结束),许多字符串函数的正确操作均是以此为基础进行。
而我们知道,在宽字符的情况下,一个字符在内存中要占据一个字的空间(即一个字符两字节),这就会使操作ANSI字符的字符串函数无法正确操作。
以”Hello”字符串为例,在宽字符下,它的五个字符是:0x0048 0x0065 0x006c 0x006c 0x006f在内存中,实际的排列是:48 00 65 00 6c 00 6c 00 6f 00于是,ANSI字符串函数,如strlen,在碰到第一个48后的00时,就会认为字符串到尾了,用strlen对宽字符串求长度的结果就永远会是1!在许多多字节字符集中,0x00 到0x7F 范围内的每个字符都与ASCII 字符集中具有相同值的字符相同。
(4)用宏实现对ANSI和Unicode通用的编程可见,C++有一整套的数据类型和函数实现Unicode编程,也就是说,您完全可以使用C++实现Unicode编程。
如果我们想要我们的程序有两个版本:ANSI版本和Unicode版本。
当然,编写两套代码分别实现ANSI版本和Unicode版本完全是行得通的。
但是,针对ANSI字符和Unicode字符维护两套代码是非常麻烦的事情。
为了减轻编程的负担,C++定义了一系列的宏,帮助您实现对ANSI和Unicode的通用编程。
C++宏实现ANSI和Unicode的通用编程的本质是根据”_UNICODE”(注意,有下划线)定义与否,这些宏展开为ANSI或Unicode字符(字符串)。
#ifdef _UNICODEtypedef wchar_t TCHAR; // 定义了_UNICODE宏的情况下,TCHAR是两个字节的字符#define __T(x) L##x// ##是ANSI C标准的预处理语法,它叫做“粘贴运算符”,即将前面的L与宏参数合在一起。
#define _T(x) __T(x) // _T(x)一个下划线的变成__T(x)两个下划线的#else#define __T(x) x // 未定义_UNICODE宏的情况下,TCHAR是一个字节的字符typedef char TCHAR; // 非宽字符的字符串常量#endif*.几个预编译指令的用法# 字符串化运算符,其主要效果是把参数的名字转换为字符串。
Example: // 1. *.h中定义#define STRINGLIZE(ivalue) #ivalue// *.cpp中定义CString strTmp = STRINGLIZE(2);AfxMessageBox(strTmp);// 结果是:弹出消息框中显示2,说明可以变成字符串// 2.#define STRINGLIZE(ivalue) printf(#ivalue " is: %d", ivalue)// 使用STRINGLIZE(2);// 结果是:2 is: 2,将ivalue的值与后面的字符串合并成一个字符串了// 注:以下这情况使用时的结果会有不同int a = 2;STRINGLIZE(a);// 1. 结果是:弹出消息框中显示a// 2. 结果是:a is: 2注意:预处理的意思就是在编译运行前按字面处理,## 粘贴运算符,即它先进行宏替换,再进行连接。
Example: #define MACR1 printf("MACR1 is invoked.")#define MACR2 printf("MACR2 is invoked.")#define MAKE_MACR(n) MACR ## n// 使用时MAKE_MACR(2); // -->相当于调用了宏MACR2// 结果是:MACR2 is invoked.// 2.#define STRINGLIZE(ivalue) TRACE("ivalue is: %d", ivalue##ivalue)STRINGLIZE(2);// 2. 结果是:ivalue is: 22// 3.int a = 2;STRINGLIZE(a);// 3. 结果是:error C2065: 'aa' : undeclared identifier#@ 字符化运算符Example: #define CHARIZEIT(x) #@x// 使用char c = CHARIZEIT(z);// 结果是:c = 'z'#include 包含一个源代码文件Example: #include /#include "my.h"/#include "t.c"#define 定义宏Example: #define MAX_NUM 10/#define max(x,y) (x) > (y) ? (x) : (y);#define可以替代多行的代码,例如MFC中的宏定义:#define MACRO(arg1, arg2) do {语句;}while(条件)关键是要在每一个换行的时候加上一个""。
#undef 取消已定义的宏#if 如果给定条件为真,则编译下面代码#ifdef 如果宏已经定义,则编译下面代码#ifndef 如果宏没有定义,则编译下面代码#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码#endif 结束一个#if/#ifdef/#ifndef...#else条件编译块#error 停止编译并显示错误信息#line 指令可以改变编译器用来指出警告和错误信息的文件号和行号。
#pragma 指令没有正式的定义。
编译器可以自定义其用途。
四、使用Win32 API进行Unicode编程Win32 API中定义了一些自己的字符数据类型。
这些数据类型的定义在winnt.h头文件中。
例如:typedef char CHAR;typedef unsigned short WCHAR; // wc, 16-bit UNICODE charactertypedef CONST CHAR *LPCSTR, *PCSTR;Win32 API在winnt.h头文件中定义了一些实现字符和常量字符串的宏进行ANSI/Unicode通用编程。
同样,只例举几个最常用的:#ifdef UNICODE // 注意此处没有没有下划线typedef WCHAR TCHAR, *PTCHAR;typedef LPWSTR LPTCH, PTCH;typedef LPWSTR PTSTR, LPTSTR;typedef LPCWSTR LPCTSTR;#define __TEXT(quote) L##quote // r_winnt#else // r_winnttypedef char TCHAR, *PTCHAR;typedef LPSTR LPTCH, PTCH;typedef LPSTR PTSTR, LPTSTR;typedef LPCSTR LPCTSTR;#define __TEXT(quote) quote // r_winnt#endif // r_winntAPI的字符串操作函数和C++的操作函数可以实现相同的功能,所以,如果需要的话,建议您尽可能使用C++的字符串函数,没必要去花太多精力再去学习API的这些东西。