您的位置 首页 > 数码极客

文本如何转utf-8、文本如何转换为表格格式

一个字符串从定义到处理再到输出,涉及到编辑器、编译器和输出环境三个因素,正确的处理和显示需要三个因素的共同保障,每一个环节都不能出错。

代码编辑器采用何种编码方式决定了字符串最初的编码,比如编辑器如果采用GBK,那么代码文件中的所有字符都是以GBK编码存储。当编译器处理字符串时,可以通过前缀来判断字符串的编码类型,如果目标编码与原编码不同,则编译器会进行转换,比如C++11中的前缀u8表示目标编码为utf-8的字符,如果代码文件采用的是GBK,编译器按照UTF-8去解析字符串常量,则可能会出现错误。

Ansi字符串我们最熟悉,英文占一个字节,汉字2个字节,以一个\0结尾,常用于txt文本文件。

Unicode字符串,每个字符(汉字、英文字母)都占2个字节,以2个连续的\0结尾,NT操作系统内核用的是这种字符串,常被定义为typedef unsigned short wchar_t; 所以我们有时常会见到什么char*无法转换为unsigned short*之类的错误,其实就是unicode。

UTF-8是 Unicode一种压缩形式,英文A在unicode中表示为0x0041,老外觉得这种存储方式太浪费,因为浪费了50%的空间,于是就把英文压缩成1 个字节,成了utf-8编码,但是汉字在utf-8中占3个字节,显然用做中文不如ansi合算,这就是中国的网页用作ansi编码而老外的网页常用utf-8 的原因。

UTF-8在还游戏里运用的很广泛,比如WOW的lua脚本等。

以下是UTF-8与Unicode的标识位、换行符与字节数:

UTF-8-bom

标识位:0XBFBBEF(3个字节)

换 行符:0x0A0D

汉字采用三个字节编码

UTF-8

标识位:无

换行符:0X0A0D

汉字采用三个字节编码

Unicode Big Endian(UTF-16/UCS-2大端字节序

Unicode little Endian(UTF-16/UCS-2小端字节序

标识位:0xFFFE

换行符标识位:0x0A000D00

汉字编码:采用2个字节

UTF-8编码的Unicode数据,C++11还是使用了8bits宽度的char类型数组来表示。

以下是将一个编辑框的文本插入到utf-8文件的实例:

1 CString→wchar_t

wchar_t* wszString = new();

2 求wszString的字节数,动态分配空间,并赋值;

3 在文件头部写入utf-8标识符0XBFBBEF:

cFile.Write("\xef\xbb\xbf", 3);

4 将转换后的文本写入文本。

void TextBox::OnButton45() // 插入文本到utf-8文件 { CString newstr; GetDlgItem(IDC_textbox)->GetWindowText(newstr); new("<<","<<"); new("#include <","#include <"); new("#include<","#include<"); new("\n",""); i() < 3) m_status = "大文本框中内容不能少于3个字符,不能超过34245个字符"; else { CFile cFile; i(_T(m_fname),CFile::modeNoTruncate|CFile::modeWrite)) { //下面可能用string的Find()要好些 i("<p>",0) == 0 || new("<p>",0) == 0) //if(newstr[0] == '<' & newstr[1] == 'p' & newstr[2] == '>') { new("?</p>","</p>"); // unicode to UTF8 wchar_t* wszString = new(); //预转换,得到所需空间的大小,这次用的函数和上面名字相反 int u8Len = ::WideCharToMultiByte(CP_UTF8, NULL, wszString, wcslen(wszString), NULL, 0, NULL, NULL); //同上,分配空间要给'\0'留个空间 //UTF8虽然是Unicode的压缩形式,但也是多字节字符串,所以可以以char的形式保存 char* szU8 = new char[u8Len + 1]; //转换 //unicode版对应的strlen是wcslen ::WideCharToMultiByte(CP_UTF8, NULL, wszString, wcslen(wszString), szU8, u8Len, NULL, NULL); //最后加上'\0' szU8[u8Len] = '\0'; //MessageBox不支持UTF8,所以只能写文件 //写文本文件,UTF8的BOM是0xbfbbef //文件开头 cFile.SeekToBegin(); //写BOM,同样低位写在前 cFile.Write("\xef\xbb\xbf", 3); //写入内容 cFile.SeekToEnd(); (sUNICODE,sizeof(sUNICODE)); //将文件变为UNICODE编码 cFile.Write(szU8, u8Len * sizeof(char)); cFile.Flush(); cFile.Close(); delete[] szU8; szU8 =NULL; GetDlgItem(IDC_textbox)->SetWindowText(""); m_status = "文本已保存至" + m_fname; UpdateData(0); } else { TextBox::OnButton13(); m_status = "文本已添加<p></p>"; UpdateData(0); } } } GetDlgItem(IDC_textbox)->SetFocus(); UpdateData(0); }

以下是各类型转换的较为通用的C++版本:

//C++写入UTF-8格式的文件 #include <windows.h> //WideCharToMultiByte() #include <wc; #include <fstream> #include <iostream> using namespace std; class CChineseCode { public: static void UTF_8ToUnicode(wchar_t* pOut,char *pText); // 把UTF-8转换成Unicode static void UnicodeToUTF_8(char* pOut,wchar_t* pText); //Unicode 转换成UTF-8 static void UnicodeToGB2312(char* pOut,wchar_t uData); // 把Unicode 转换成 GB2312 static void Gb2312ToUnicode(wchar_t* pOut,char *gbBuffer);// GB2312 转换成 Unicode static void GB2312ToUTF_8(string& pOut,char *pText, int pLen);//GB2312 转为 UTF-8 static void UTF_8ToGB2312(string &pOut, char *pText, int pLen);//UTF-8 转为 GB2312 }; void CChineseCode::UTF_8ToUnicode(wchar_t* pOut,char *pText) { char* uchar = (char *)pOut; uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F); uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F); return; } void CChineseCode::UnicodeToUTF_8(char* pOut,wchar_t* pText) { // 注意 WCHAR高低字的顺序,低字节在前,高字节在后 char* pchar = (char *)pText; pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4)); pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6); pOut[2] = (0x80 | (pchar[0] & 0x3F)); return; } void CChineseCode::UnicodeToGB2312(char* pOut,wchar_t uData) { WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(wchar_t),NULL,NULL); return; } void CChineseCode::Gb2312ToUnicode(wchar_t* pOut,char *gbBuffer) { ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1); return ; } void CChineseCode::GB2312ToUTF_8(string& pOut,char *pText, int pLen) { char buf[4]; int nLength = pLen* 3; char* rst = new char[nLength+1]; memset(buf,0,4); memset(rst,0,nLength); int i = 0; int j = 0; while(i < pLen) { //如果是英文直接复制就可以 if( *(pText + i) >= 0) { rst[j++] = pText[i++]; } else { wchar_t pbuffer; Gb2312ToUnicode(&pbuffer,pText+i); UnicodeToUTF_8(buf,&pbuffer); unsigned short int tmp = 0; tmp = rst[j] = buf[0]; tmp = rst[j+1] = buf[1]; tmp = rst[j+2] = buf[2]; j += 3; i += 2; } } rst[j] = '\0'; //返回结果 pOut = rst; delete [] rst; return; } void CChineseCode::UTF_8ToGB2312(string &pOut, char *pText, int pLen) { char * newBuf = new char[pLen+1]; char Ctemp[4]; memset(Ctemp,0,4); int i =0; int j = 0; while(i < pLen) { if(pText[i] > 0) { newBuf[j++] = pText[i++]; } else { WCHAR Wtemp; UTF_8ToUnicode(&Wtemp,pText + i); UnicodeToGB2312(Ctemp,Wtemp); newBuf[j] = Ctemp[0]; newBuf[j + 1] = Ctemp[1]; i += 3; j += 2; } } newBuf[j] = '\0'; pOut = newBuf; delete [] newBuf; return; } void main(void) { ofstream ofOut("11.txt") ; std::string strTemp("我叫石海龙\n") ; CChineseCode::GB2312ToUTF_8(strTemp, (char*(), ()) ; ofOut << () ; o() ; }

-End-

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

</