C++读UNICODE文本
来源:互联网 发布:淘宝客佣金代扣款 编辑:程序博客网 时间:2024/05/17 01:09
熟悉一下字符类型,char, wchar_t, tchar,最熟悉的char是单字节字符,适用于ansi编码;wchar_t
是双字节的宽字符类型,适用于unicode编码;tchar是一个宏,在ansi坏境下定义为char,unicode
坏境下定义为wchar_t。
怎么来表示字符串?对,字符数组,要知道在c++语言里面,其实没有数组的数据结构,所谓数组,都
是由指针+长度来表示。字符型指针const char *, const wchar_t *, const tchar *可以用来在不同的环
境下表示字符串。再说相关的几个宏,lpstr: long point string, 相当于char *; lpcstr: long point
const string, 相当于 const char *; lpcwstr: long point const wide string, 相当于 const wchar_t *;
和 "用c++读写unicode文本" 有关的c#、asp.net、c++编程小帖士:
strong>DOC对象.CreateElement("新建节点名");创建XML文档新节点
lpctstr: 类似的,相当于 const tchar *; 这些都不要死记硬背,记着大写字母的意思即可猜出其含义
。
一个字符串,比如说"北京2008",对应ansi编码表示为 const char * cha = "北京2008"; unicode编码
表示为 const wchar_t * wcha = l"北京2008"; 。在内存里以二进制存储,ansi编码对应为 0x b1b1
bea9 32 30 30 38,unicode编码为 0x 1753 ac4e 3200 3000 3000 3800。
回到上面,为什么字符型指针可以表示一个字符串?计算机找到这个指针,只能知道串首字符,这里因
为字符串有个默认的结束符'/0'(ansi或者ascii表示为0x00),从首字符开始,计算机开始向后查找直
到0x00,认为字符串结束,所以存储字符串的时候,计算机是带着一个特殊结束符的。可是要注意了,
这个结束符0x00是ascii码定义的结束符啊,那么在宽字符unicode环境下呢?结束符是什么?是
0x0000。
而对于非const字符串,怎么表示?char * 方法怎么动态定义长度?好办,可以用new手动分配内存空间
,除此之外,还有更好办的方法,那就是字符串类型string, 怎么可变长度,怎么记录长度,内存怎么存
储,这些都不用管,都有c++标准库自动管理。
不同类型的字符串间之间怎么转换?比如定义 char * cha; string str; str = cha; // 可以实现 char * 到
string 的转换, cha = str.c_str(); 可以从 string 转换到 char *;对于wchar_t wcha; wstring wstr; 呢
?wstr = wcha; wcha = wstr.c_str(); // 这个是否可以呢?!
说过了字符串的表示和类型转换,再来看字符流i/o,c++里面的fstream, ifstream, ofstream, 文件流
的i/o有好多种方式,默认为字符流方式,明确的说是ansi字符流,都是针对ansi文本的,那么
unicode怎么读写呢?
c++里倒真有wfsteam流的,可惜用起来也很奇怪,用wifstream读取unicode文本,结果竟然是读取一
个字节,加上一个0x00,在读取下一个字节,如此!比如文本里保存的还是“北京2008”,刚才说过
unicode编码为 0x 1753 ac4e 3200 3000 3000 3800;用wifstream读到内存的字符竟是 0x 1700
5300 ac00 4e00 ... 这叫什么unicode?我不知道wfstream怎么正确使用用,有知道的朋友还请不吝告
知!
既然wftream不行,那么怎么读取unicode呢,这里可以借鉴一下二进制流的读写方式,二进制流在读写
时必须明白存储单位的数据结构,定义为结构体,然后逐n字节(n为结构长度)按二进制读取;这个可
以借鉴过来,不用定义结构了,直接用wchar_t,代码如下:
ifstream fin;
fin.open(filename, ios::binary);
// 跳过unicode文本开头有两个字节0xfffe(称作bom,用于标识unicode编码)
fin.seek(2, ios::beg);
while (!fin.eof())
{
wchar_t wch;
fin.read((char *)(&wch), 2);
}
如果要按行读取,怎么办?好了,有ifstream的成员函数getline(cha, size),还有string类成员函数
getline(fin, str)。你试试能不能用在unicode下使用?答案是否定的!为什么?因为getline函数默认在
ansi下使用,它对换行符的判断是基于ascii码的换行(0x0d)和行开头标记(0x0a),如果把它用在
unicode编码下,比如“不”字,unicode编码为0x0d4e。当getline函数执行到这,以为换行了,所以
说会失效!那么unicode换行符以及行开头符的二进制是什么?双字节了,是0x0d00和0x0a00,这时候
getline函数就失效了,怎么办,手动判断:
ifstream fin;
fin.open(filename, ios::binary);
size_t index = 2;
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);
iline++;
index += 4; // 跳过回车符和行开头符
}
else
{
wstrline.append(1, wch);
index += 2;
}
}
上面的程序可以读取unicode了,那么读了进来怎么理解unicode呢,这就需要char * 和 wchar_t *间的
转换了,这个没有简便的方法,ansi、unicode两种编码之间的转换,只能靠查表实现,c++提供了
两个函数,wcstombs(_dest, _source, _dsize) 从unicode编码转化为ansi编码 ,mbstowcs(_dest,
_source, _dsize)反之,参数对应为const char*, const wchar_t*以及长度。这里在提供一个网上的函数
,用于实现string和wstring的转换:
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::wstring s2ws(const std::string& s)
{
setlocale(lc_all, "chs");
const char* _source = s.c_str();
size_t _dsize = s.size() + 1;
wchar_t *_dest = new wchar_t[_dsize];
wmemset(_dest, 0, _dsize);
mbstowcs(_dest,_source,_dsize);
std::wstring result = _dest;
delete []_dest;
setlocale(lc_all, "c");
return result;
}
写到这里,就可以用c++读取unicode文本了,写的方法类似。
- C++读UNICODE文本
- c++ifstream写入unicode编码格式的文本
- CStdioFileEx读取Unicode文本
- C++读写unicode文本
- C++读取unicode文本
- C++读取unicode文本
- unicode方式保存文本
- Unicode字符串写入文本
- 在GDB中查看 C/C++ Unicode文本变量内容(wchar_t*)
- 在GDB中查看 C/C++ Unicode文本变量内容(wchar_t*)
- Unicode下将ansi文本转换成Unicode文本
- 用C++读写unicode文本
- 用C++读写unicode文本
- 用C++读写unicode文本
- EVC上读取UNICODE 文本
- 用C++读写unicode文本
- 用C++读写unicode文本
- 用C++读写unicode文本
- Tran
- DOC
- Jbpm
- VS2005内存泄漏检测方法
- work
- C++读UNICODE文本
- DirectX全屏双显示器调试
- Unicode下wstring(wchar_t*)和string(char*)互相转换
- DirectX窗口模式一
- 人生不能停滞,有时需要换种方式扔掉过去,改变前进的轨迹 (图)
- DirectX窗口模式二
- 利用mysqlcheck命令快速修复mysql数据库
- 55个经典开源Windows工具
- c++中调用汇编