Ansi、Unicode、UTF8字符串之间的转换和写入文本文件
转载请注明出处http://www.cppblog.com/greatws/archive/2008/08/31/60546.html
最近有人问我关于这个的问题,就此写一篇blog
Ansi字符串我们最熟悉,英文占一个字节,汉字2个字节,以一个\0结尾,常用于txt文本文件
Unicode字符串,每个字符(汉字、英文字母)都占2个字节,以2个连续的\0结尾,NT操作系统内核用的是这种字符串,常被定义为typedef unsigned short wchar_t;所以我们有时常会见到什么char*无法转换为unsigned short*之类的错误,其实就是unicode
UTF8是Unicode一种压缩形式,英文A在unicode中表示为0x0041,老外觉得这种存储方式太浪费,因为浪费了50%的空间,于是就把英文压缩成1个字节,成了utf8编码,但是汉字在utf8中占3个字节,显然用做中文不如ansi合算,这就是中国的网页用作ansi编码而老外的网页常用utf8的原因。
UTF8在还游戏里运用的很广泛,比如WOW的lua脚本等
下面来说一下转换,主要用代码来说明吧
写文件我用了CFile类,其实用FILE*之类的也是一样,写文件和字符串什么类别没有关系,硬件只关心数据和长度
Ansi转Unicode
介绍2种方法
{
// ansi to unicode
char* szAnsi = "abcd1234你我他";
//预转换,得到所需空间的大小
int wcsLen = ::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), NULL, 0);
//分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间
wchar_t* wszString = new wchar_t[wcsLen + 1];
//转换
::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), wszString, wcsLen);
//最后加上'\0'
wszString[wcsLen] = '\0';
//unicode版的MessageBox API
::MessageBoxW(GetSafeHwnd(), wszString, wszString, MB_OK);
//接下来写入文本
//写文本文件,头2个字节0xfeff,低位0xff写在前
CFile cFile;
cFile.Open(_T("1.txt"), CFile::modeWrite | CFile::modeCreate);
//文件开头
cFile.SeekToBegin();
cFile.Write("\xff\xfe", 2);
//写入内容
cFile.Write(wszString, wcsLen * sizeof(wchar_t));
cFile.Flush();
cFile.Close();
delete[] wszString;
wszString =NULL;
//方法2
//设置当前地域信息,不设置的话,使用这种方法,中文不会正确显示
//需要#include<locale.h>
setlocale(LC_CTYPE, "chs");
wchar_t wcsStr[100];
//注意下面是大写S,在unicode中,代表后面是ansi字符串
//swprintf是sprintf的unicode版本
//格式的前面要加大写L,代表是unicode
swprintf(wcsStr, L"%S", szAnsi);
::MessageBoxW(GetSafeHwnd(), wcsStr, wcsStr, MB_OK);
}
Unicode转Ansi
也是2种方法
{
// unicode to ansi
wchar_t* wszString = L"abcd1234你我他";
//预转换,得到所需空间的大小,这次用的函数和上面名字相反
int ansiLen = ::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
//同上,分配空间要给'\0'留个空间
char* szAnsi = new char[ansiLen + 1];
//转换
//unicode版对应的strlen是wcslen
::WideCharToMultiByte(CP_ACP, NULL, wszString, wcslen(wszString), szAnsi, ansiLen, NULL, NULL);
//最后加上'\0'
szAnsi[ansiLen] = '\0';
//Ansi版的MessageBox API
::MessageBoxA(GetSafeHwnd(), szAnsi, szAnsi, MB_OK);
//接下来写入文本
//写文本文件,ANSI文件没有BOM
CFile cFile;
cFile.Open(_T("1.txt"), CFile::modeWrite | CFile::modeCreate);
//文件开头
cFile.SeekToBegin();
//写入内容
cFile.Write(szAnsi, ansiLen * sizeof(char));
cFile.Flush();
cFile.Close();
delete[] szAnsi;
szAnsi =NULL;
//方法2
//和上面一样有另一种方法
setlocale(LC_CTYPE, "chs");
char szStr[100];
//注意下面是大写,在ansi中,代表后面是unicode字符串
//sprintf
sprintf(szStr, "%S", wszString);
::MessageBoxA(GetSafeHwnd(), szStr, szStr, MB_OK);
}
Unicode转UTF8
{
// unicode to UTF8
wchar_t* wszString = L"abcd1234你我他";
//预转换,得到所需空间的大小,这次用的函数和上面名字相反
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 cFile;
cFile.Open(_T("1.txt"), CFile::modeWrite | CFile::modeCreate);
//文件开头
cFile.SeekToBegin();
//写BOM,同样低位写在前
cFile.Write("\xef\xbb\xbf", 3);
//写入内容
cFile.Write(szU8, u8Len * sizeof(char));
cFile.Flush();
cFile.Close();
delete[] szU8;
szU8 =NULL;
}
UTF8转UNICODE
{
//UTF8 to Unicode
//由于中文直接复制过来会成乱码,编译器有时会报错,故采用16进制形式
char* szU8 = "abcd1234\xe4\xbd\xa0\xe6\x88\x91\xe4\xbb\x96\x00";
//预转换,得到所需空间的大小
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
//分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间
wchar_t* wszString = new wchar_t[wcsLen + 1];
//转换
::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
//最后加上'\0'
wszString[wcsLen] = '\0';
//unicode版的MessageBox API
::MessageBoxW(GetSafeHwnd(), wszString, wszString, MB_OK);
//写文本同ansi to unicode
}
Ansi转换utf8和utf8转换Ansi就是上面2个的结合,把unicode作为中间量,进行2次转换即可
Ansi、Unicode、UTF8字符串之间的转换和写入文本文件相关推荐
- C++中Ansi、Unicode、UTF8字符串之间的转换和写入
转自: http://dark0729.blogbus.com/logs/51496111.html Ansi字符串我们最熟悉,英文占一个字节,汉字2个字节,以一个\0结尾,常用于txt文本文件 Un ...
- unicode和字符串之间的转换有两种方式
unicode和字符串之间的转换有两种方式. 1.1.通过JDK自带的"native2ascii"进行转换 首先,您测试的机器需要安装JDK,比如我的机器环境,我的JDK安 ...
- C#_汉字与GBK,Unicode,UTF-8编码之间的转换
IT发展至今,字符编码版本众多,目前流行的GBK,Unicode,UTF-8编码与汉字的转换可用如下代码: private void button1_Click(object sender, Even ...
- 字符串处理 - ANSI - Unicode - UTF8 转换
字符串处理 - ANSI - Unicode - UTF8 转换 [C语言]字符串处理 - ANSI - Unicode - UTF8 转换 2008-11-4: 使用MultiByteToWideC ...
- pythonunicode和str_python2 中 unicode 和 str 之间的转换及与python3 str 的区别
在python2中字符串分为 unicode 和 str 类型 Str To Unicode 使用decode(), 解码 Unicode To Str 使用encode(), 编码 返回数据给前端时 ...
- Unicode16 与 UTF-8编码之间的转换
Unicode16 与 UTF-8 中文编码之间的转换 头文件 #include <string> #include <locale> #include <codecvt ...
- JSON对象与字符串之间的转换
JSON对象与字符串之间的转换 JSON转换成字符串 字符串转换成JSON JavaScript中内置了一个JSON对象,可以用来进行JSON与字符串之间的转换. JSON转换成字符串 使用:JSON ...
- 为什么需要java包装类,装箱拆箱,基本类型与字符串之间的转换,java数据类型
为什么需要包装类? 首先,Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,将每个基本数据类型设计一个对应的类进行代表,这种方式增强了Java面向对象的性质. 其次,如果 ...
- Python bytes字节串与string字符串之间的转换
目录 背景 代码 总结 背景 在工作中经常会碰到字节串(bytes)与字符串(string)之间转换的问题,做个记录. bytes只负责用字节序列的形式(二进制形式)存储数据,不关心数据本身是图片.文 ...
最新文章
- 利用bigpipe机制实现页面模块的异步渲染 chunked技术
- Gut:人体口腔菌群的稳定性和动态变化规律
- 别拒绝生命中偶尔的初恋
- “证券教父”阚治东旗下东方汇富成失信被执行人 官方澄清
- 玩转Mixly – 3、Arduino AVR编程 之 控制
- boost::graph模块实现包含平均测地线示例
- ie11不识别html5影片,IE11无法显示flash?IE11无法播放视频的解决方法
- dataAdapter与dataSet和dataTable的填充
- 计算机主板用塑料做的好吗,电脑主板包装的塑料袋为什么是用透明胶封的,这样...-卓优商学问答...
- php输出mysql查询结果_PHP简单获取数据库查询结果并返回JSON
- java dna框架_DNA (Java代码)
- webpack多个Html,使用webpack构建多页面应用
- Windows下Netcat安装
- C++ SHFileOperation实现文件、文件夹拷贝、删除、重命名
- Numpy简易教程7——读/写文件
- JS中Key-Value操作
- 14、TWS API和IB中的账户和投资组合数据
- Java8集合之HashMap的hash计算、扩容等问题
- 信息安全概论———概述
- Windows 10 系统下载网址推荐
热门文章
- [转]2006年十二星座运程 目录
- 如何击败Python的问题
- matlab软件imag函数_「复变函数与积分变换」基本计算代码
- 电子表格转换成数据库_创建数据库,将电子表格转换为关系数据库,第1部分...
- leetcode 690. 员工的重要性(dfs)
- leetcode 376. 摆动序列(dp)
- 整数存储怎么转化为浮点数_非整数值如何存储在浮点数中(以及为什么要浮点数)...
- 3c技能和背包需要改建吗?_认为您需要仪表板? 您应该改建一个笔记本。
- 谷歌跟oracle_谁赢得了Google VS Oracle? 开发人员赢了。
- LoadRunner11支持的浏览器小结