VC Unicode工程读写文本文件
2010-12-27 23:45
204 查看
参考文章:http://blog.csdn.net/wuchen1004/archive/2010/08/03/5786537.aspx
http://www.codeproject.com/KB/files/ConfigString.aspx
因为Windows底层处理字符串是以Unicode形式处理的,所以现在一般使用VC开发软件时都选择Unicode的工程。
在Unicode工程中,读写文本文件就会有一个比较纠结的问题:
一般情况下我们新建和编辑的文本文件都是ANSI格式的,而在ANSI工程中用着十分方便的CStdioFile读取字符串时
使用的是CString类型, 这就导致Unicode工程环境下CStdioFile将Ansi的字符串读取到了CStringW类型中,
即使想使用CA2W来转, 也会出现类型不匹配的错误。
这种情况下,只好自己使用MultiByteToWideChar这类API来转换,实际编码时总是不太方便。但是即使使用这种方法还是
比直接使用ReadFile来读取文件要方便一些, 因为毕竟不需要自己处理换行。
目前来看Unicode工程环境下读取ansi文件最方便的还是使用fstream,这种方法不仅可以读取一行文本,还可以很方便的读取一行中的多个数字或者单词(参见后面的实例代码)。在CodeProject上有一篇文章,封装了两个读取ansi和unicode字符串的函数,他是直接使用fgetc和fgetwc来读取字符,这种方法本质上跟ReadFile差不多。
另外值得注意的是,一般情况下创建一个新文件都是Ansi类型的,要创建unicode文件需要在文件的前两个字节写入0xFFFE。
因为unicode文件开头这两个字节的原因,使用fstream读取unicode文件会有问题,请见代码示例。
http://www.codeproject.com/KB/files/ConfigString.aspx
因为Windows底层处理字符串是以Unicode形式处理的,所以现在一般使用VC开发软件时都选择Unicode的工程。
在Unicode工程中,读写文本文件就会有一个比较纠结的问题:
一般情况下我们新建和编辑的文本文件都是ANSI格式的,而在ANSI工程中用着十分方便的CStdioFile读取字符串时
使用的是CString类型, 这就导致Unicode工程环境下CStdioFile将Ansi的字符串读取到了CStringW类型中,
即使想使用CA2W来转, 也会出现类型不匹配的错误。
这种情况下,只好自己使用MultiByteToWideChar这类API来转换,实际编码时总是不太方便。但是即使使用这种方法还是
比直接使用ReadFile来读取文件要方便一些, 因为毕竟不需要自己处理换行。
目前来看Unicode工程环境下读取ansi文件最方便的还是使用fstream,这种方法不仅可以读取一行文本,还可以很方便的读取一行中的多个数字或者单词(参见后面的实例代码)。在CodeProject上有一篇文章,封装了两个读取ansi和unicode字符串的函数,他是直接使用fgetc和fgetwc来读取字符,这种方法本质上跟ReadFile差不多。
另外值得注意的是,一般情况下创建一个新文件都是Ansi类型的,要创建unicode文件需要在文件的前两个字节写入0xFFFE。
因为unicode文件开头这两个字节的原因,使用fstream读取unicode文件会有问题,请见代码示例。
int CCTextFile_TestDlg::CStdioFileTest(void) { CStdioFile file; CString line; // Read ANSI File file.Open( _T( "test_ansi.txt" ), CFile::modeRead ); while ( file.ReadString( line ) ) { OutputDebugString( line ); // 汉字乱码 } file.Close(); // Read Unicode File file.Open( _T( "test_unicode.txt" ), CFile::modeRead ); while ( file.ReadString( line ) ) { OutputDebugString( line ); // 乱码 } file.Close(); // 写文件, 得到的文件是ansi文件 file.Open( _T( "test_stdiofile.txt" ), CFile::modeCreate | CFile::modeWrite ); file.WriteString( _T( "CStdioFile Test:" ) ); // 成功 file.WriteString( _T( "测试Unicode!/n" ) ); // 写入失败 file.Close(); return 0; } int CCTextFile_TestDlg::StreamTest(void) { // 读取Ansi文件 std::ifstream isin; isin.open( _T( "test_ansi.txt" ), ios::in | ios::binary ); if ( isin ) { // 读取一行 string line; getline( isin, line ); OutputDebugString( CA2W( line.c_str() ) ); // 读取 字符串 和 数字, 这是stream 读取文件的方便之处 string line2; int row; isin>>line2>>row; CString tmp = CA2W( line2.c_str() ); tmp.AppendFormat( _T( " %d" ), row ); OutputDebugString( tmp ); isin.close(); } // 读取Unicode 文件 std::wifstream isinu; isinu.open( _T( "test_unicode.txt" ), ios::in | ios::binary ); if ( isinu ) { // 读取一行 wstring line; while ( getline( isinu, line ) ) { OutputDebugString( line.c_str() );// 乱码, 读取失败, 因为 FFFE开头 } isinu.close(); } // 写一个ansi文件, 没有问题 ofstream aof; aof.open( _T( "test_ofstream.txt" ) ); if ( aof ) { aof<<"stream ansi test第一行!"<<endl; aof<<123<<" "<<456<<endl; aof.close(); } // 写文件, 得到仍然是ansi文件, 写入英文成功 wofstream of; of.open( _T( "test_wofstream.txt" ) ); if ( of ) { of<<_T( "stream unicode test第一行!" )<<endl; // 写入汉字失败 of<<123<<L" "<<456<<endl; of.close(); } return 0; } int CCTextFile_TestDlg::Line2FileTest(void) { FILE * fileAnsi = NULL; FILE * fileUni = NULL; // 读取Ansi文件 fileAnsi = fopen( "test_ansi.txt", "rb" ); if ( fileAnsi != NULL ) { string line; while ( LineFromFile( fileAnsi, line ) ) { OutputDebugString( CA2W( line.c_str() ) ); } fclose( fileAnsi ); } fileUni = fopen( "test_unicode.txt", "rb" ); if ( fileUni != NULL ) { wstring line; while ( LineFromFile( fileUni, line ) ) { // Unicode 文件开头的 FFEE被打印成了‘?’, 没有跳过 OutputDebugString( line.c_str() ); } fclose( fileUni ); } // 写一个Ansi文件 fileAnsi = fopen( "test_line_ansi.txt", "wb" ); if ( fileAnsi != NULL ) { LineToFile( fileAnsi, "ansi file 第一行!" ); LineToFile( fileAnsi, "line 2" ); fclose( fileAnsi ); } // 写文件, 得到的是ansi文件, 但是字符串是unicode编码的 fileUni = fopen( "test_line_unicode.txt", "wb" ); if ( fileUni != NULL ) { LineToFile( fileUni, L"unicode file 第一行!" ); // 成功 LineToFile( fileUni, L"Line 2" ); fclose( fileUni ); } return 0; }
相关文章推荐
- VC 编程ANSI环境下读写Unicode文件和将CStdioFile类扩展,读取UNICODE文本文件
- VC 编程ANSI环境下读写Unicode文件和将CStdioFile类扩展,读取UNICODE文本文件
- VC 编程ANSI环境下读写Unicode文件和将CStdioFile类扩展,读取UNICODE文本文件
- VC 编程ANSI环境下读写Unicode文件和将CStdioFile类扩展,读取UNICODE文本文件
- VC 编程ANSI环境下读写Unicode文件和将CStdioFile类扩展,读取UNICODE文本文件
- VC读写指定分隔符的UNICODE文本文件
- VC 编程ANSI环境下读写Unicode文件
- VC修改CStdioFile类, 兼容一行一行读写Unicode的和非Unicode的log
- VC++的UNICODE工程一些常用转码
- 文件对话框读写文本文件[VC]
- vc 设置工程为unicode
- 为vc工程添加Unicode
- VC++的UNICODE工程一些常用转码
- CstdioFileEx读写UNICODE文本文件
- vc中unicode读写文件CStdioFile
- VC 编程ANSI环境下读写Unicode文件
- VC++的UNICODE工程和多字节字符集的HTTP请求
- 创建Unicode版本的VC工程
- VC++的UNICODE工程一些常用转码
- vc工程是unicode模式下必须完全的放弃char