如何在Unicode字符集下读写中文的txt文件

时间:2022-04-19 20:20:33
     最近使用CFile::read和CFile::write读写中文的txt文件,但是好像只能在非Unicode字符集中才可以,否则中文都是乱码。
     用CStdioFile类读写更是不行。
     由于vs2008环境下,非Unicole的窗体和控件风格是Windows经典样式,而不是Windows XP样式。

我的问题是:

1.如何在Unicode字符集下读写中文的txt文件。
2.或者,在非Unicode字符集下,如何继续使用Windows XP样式的窗体和控件风格。

     敬请高手指点,感激不尽!

23 个解决方案

#1


给文件写上bom头。

#2


哦。这个我前几天用C#写过。不知道对vc管不管用。我是把txt保存为utf8。然后在C#中设置编码为utf8然后就解决了多国语言的读写问题。

#3


str=_T("你好");   
char szANSIString[MAX_PATH];   
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,str,-1,szANSIString,sizeof(szANSIString),NULL,NULL);  
file.Write(szANSIString,4);

写文件这样就行,我试过,OK的

#4


引用 1 楼 jennyvenus 的回复:
给文件写上bom头。

能说的再详细些吗?

#5


引用 2 楼 lzjdlsl 的回复:
哦。这个我前几天用C#写过。不知道对vc管不管用。我是把txt保存为utf8。然后在C#中设置编码为utf8然后就解决了多国语言的读写问题。

谢谢,txt保存为utf8怎么实现的?

#6


文件头添加两个字节0xff 0xfe就行了。

#7


引用 3 楼 martenyong 的回复:
str=_T("你好");  
char szANSIString[MAX_PATH];  
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,str,-1,szANSIString,sizeof(szANSIString),NULL,NULL);  
file.Write(szANSIString,4);

写文件这样就行,我试过,OK的


不需要打开文件吗?我加入了打开文件操作,写是可以的。可读却说找不到文件,我发现文件就在目录下啊。
如果str=m_strWrite;(m_strWrite为编辑框Value变量),那么该如何改写?

读文件代码:(读文件在Unicode和非Unicode都可以读中文,对应写代码怎么写呢?)
         CString str;
CFile f;
f.Open(_T("C:\\ts.txt"),CFile::modeReadWrite,NULL);
ULONGLONG i = f.GetLength();
UINT m =(UINT)i;
char* lpBuf = new char[m+1];
memset(lpBuf,0,m+1);
f.Read(lpBuf,m);
str = lpBuf;
GetDlgItem( IDC_READ )->SetWindowText(str);
memset(lpBuf,0,m+1);
delete lpBuf;
f.Close(); 

 

#8


如果你要使用 Unicode,就不应再用 非Unicode下的数据及函数.
比如:
用WCHAR 代替 char.

#9


引用 6 楼 tufaqing 的回复:
文件头添加两个字节0xff 0xfe就行了。

CString str = "你好";
str = "0xff0xfe"+str           //没效果啊?

#10


引用 8 楼 rayland 的回复:
如果你要使用 Unicode,就不应再用 非Unicode下的数据及函数.
比如:
用WCHAR 代替 char.

读文件是正确,写文件不知道该怎么写。
WCHAR 代替 char反而出错了。不过,还是谢谢。

#11


那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

#12


引用 3 楼 martenyong 的回复:
str=_T("你好");  
char szANSIString[MAX_PATH];  
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,str,-1,szANSIString,sizeof(szANSIString),NULL,NULL);  
file.Write(szANSIString,4);

写文件这样就行,我试过,OK的

读文件找不到文件,因为没加file.Close();

str=m_strWrite;               //(m_strWrite为编辑框Value变量)
int i=m_strWrite.GetLength(); //这里是字符数,字节数怎么取的

比如:
         CString   str   =   "abc汉字 " 
        int   i=str.GetLength(); 
        i=5//不是7?

谢谢了!

#13


引用 11 楼 tufaqing 的回复:
那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

谢谢,还是不太明白。
能举个例子吗
比如

CString str = _T("你好");
BYTE bom[2] = {0xff, 0xfe};
......

#14


用Win32API函数不行吗?writefile,readfile

#15


引用 11 楼 tufaqing 的回复:
那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

我是这么写的:
CString temp = L"123你好";
int m = temp.GetLength();
BYTE bom[2] = {0xff, 0xfe};
file.Write(bom,sizeof(BYTE)*2);
file.Write(temp,8+sizeof(BYTE)*2);
file.Close();
可以实现。
但是,读出来怎么读

#16


引用 13 楼 evan369 的回复:
引用 11 楼 tufaqing 的回复:
那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

谢谢,还是不太明白。
能举个例子吗
比如

CString str = _T("你好");
BYTE bom[2] = {0xff, 0xfe};
......

的确哦,请参照以下,可以允许.
if(!fFile.Open(szFileName,CFile::modeRead))
{
goto errHandle;
}

DWORD dwsize = fFile.GetLength();

byte* pszCurFile = new byte[dwsize+2];
if( NULL == pszCurFile )
{
goto errHandle;
}

fFile.Read(pszCurFile,dwsize);

if( 0xFF!= *(pszCurFile) || 0xFE!=*(pszCurFile+1))
{//查找unicode 文件头.进入此处表明没有unicode文件头出错.
goto ...
}

WCHAR* pwFile = (WCHAR*)(pszCurFile+2);  //文件有效内容起始指针


...以下自己分析内容

if(pszCurFile)
{//释放分配过的空间
delete [] pszCurFile;
}
fFile.Close();

#17


用CArchive类

#19


2、你看你的stdafx.h文件里最后是不是有这么一段
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

改成

#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

试试

#20


引用 19 楼 xianglitian 的回复:
2、你看你的stdafx.h文件里最后是不是有这么一段

C/C++ code
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' p……


谢谢了!非常感谢!

#21


谢谢大家的指点,学到了很多方法,受益匪浅!

#22


mark,学习。

#23


该回复于2012-08-27 15:53:49被版主删除

#1


给文件写上bom头。

#2


哦。这个我前几天用C#写过。不知道对vc管不管用。我是把txt保存为utf8。然后在C#中设置编码为utf8然后就解决了多国语言的读写问题。

#3


str=_T("你好");   
char szANSIString[MAX_PATH];   
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,str,-1,szANSIString,sizeof(szANSIString),NULL,NULL);  
file.Write(szANSIString,4);

写文件这样就行,我试过,OK的

#4


引用 1 楼 jennyvenus 的回复:
给文件写上bom头。

能说的再详细些吗?

#5


引用 2 楼 lzjdlsl 的回复:
哦。这个我前几天用C#写过。不知道对vc管不管用。我是把txt保存为utf8。然后在C#中设置编码为utf8然后就解决了多国语言的读写问题。

谢谢,txt保存为utf8怎么实现的?

#6


文件头添加两个字节0xff 0xfe就行了。

#7


引用 3 楼 martenyong 的回复:
str=_T("你好");  
char szANSIString[MAX_PATH];  
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,str,-1,szANSIString,sizeof(szANSIString),NULL,NULL);  
file.Write(szANSIString,4);

写文件这样就行,我试过,OK的


不需要打开文件吗?我加入了打开文件操作,写是可以的。可读却说找不到文件,我发现文件就在目录下啊。
如果str=m_strWrite;(m_strWrite为编辑框Value变量),那么该如何改写?

读文件代码:(读文件在Unicode和非Unicode都可以读中文,对应写代码怎么写呢?)
         CString str;
CFile f;
f.Open(_T("C:\\ts.txt"),CFile::modeReadWrite,NULL);
ULONGLONG i = f.GetLength();
UINT m =(UINT)i;
char* lpBuf = new char[m+1];
memset(lpBuf,0,m+1);
f.Read(lpBuf,m);
str = lpBuf;
GetDlgItem( IDC_READ )->SetWindowText(str);
memset(lpBuf,0,m+1);
delete lpBuf;
f.Close(); 

 

#8


如果你要使用 Unicode,就不应再用 非Unicode下的数据及函数.
比如:
用WCHAR 代替 char.

#9


引用 6 楼 tufaqing 的回复:
文件头添加两个字节0xff 0xfe就行了。

CString str = "你好";
str = "0xff0xfe"+str           //没效果啊?

#10


引用 8 楼 rayland 的回复:
如果你要使用 Unicode,就不应再用 非Unicode下的数据及函数.
比如:
用WCHAR 代替 char.

读文件是正确,写文件不知道该怎么写。
WCHAR 代替 char反而出错了。不过,还是谢谢。

#11


那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

#12


引用 3 楼 martenyong 的回复:
str=_T("你好");  
char szANSIString[MAX_PATH];  
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,str,-1,szANSIString,sizeof(szANSIString),NULL,NULL);  
file.Write(szANSIString,4);

写文件这样就行,我试过,OK的

读文件找不到文件,因为没加file.Close();

str=m_strWrite;               //(m_strWrite为编辑框Value变量)
int i=m_strWrite.GetLength(); //这里是字符数,字节数怎么取的

比如:
         CString   str   =   "abc汉字 " 
        int   i=str.GetLength(); 
        i=5//不是7?

谢谢了!

#13


引用 11 楼 tufaqing 的回复:
那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

谢谢,还是不太明白。
能举个例子吗
比如

CString str = _T("你好");
BYTE bom[2] = {0xff, 0xfe};
......

#14


用Win32API函数不行吗?writefile,readfile

#15


引用 11 楼 tufaqing 的回复:
那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

我是这么写的:
CString temp = L"123你好";
int m = temp.GetLength();
BYTE bom[2] = {0xff, 0xfe};
file.Write(bom,sizeof(BYTE)*2);
file.Write(temp,8+sizeof(BYTE)*2);
file.Close();
可以实现。
但是,读出来怎么读

#16


引用 13 楼 evan369 的回复:
引用 11 楼 tufaqing 的回复:
那两个是二进制数,不是字符串,WriteFile的时候写。
BYTE bom[2] = {0xff, 0xfe};

谢谢,还是不太明白。
能举个例子吗
比如

CString str = _T("你好");
BYTE bom[2] = {0xff, 0xfe};
......

的确哦,请参照以下,可以允许.
if(!fFile.Open(szFileName,CFile::modeRead))
{
goto errHandle;
}

DWORD dwsize = fFile.GetLength();

byte* pszCurFile = new byte[dwsize+2];
if( NULL == pszCurFile )
{
goto errHandle;
}

fFile.Read(pszCurFile,dwsize);

if( 0xFF!= *(pszCurFile) || 0xFE!=*(pszCurFile+1))
{//查找unicode 文件头.进入此处表明没有unicode文件头出错.
goto ...
}

WCHAR* pwFile = (WCHAR*)(pszCurFile+2);  //文件有效内容起始指针


...以下自己分析内容

if(pszCurFile)
{//释放分配过的空间
delete [] pszCurFile;
}
fFile.Close();

#17


用CArchive类

#18


#19


2、你看你的stdafx.h文件里最后是不是有这么一段
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

改成

#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif

试试

#20


引用 19 楼 xianglitian 的回复:
2、你看你的stdafx.h文件里最后是不是有这么一段

C/C++ code
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' p……


谢谢了!非常感谢!

#21


谢谢大家的指点,学到了很多方法,受益匪浅!

#22


mark,学习。

#23


该回复于2012-08-27 15:53:49被版主删除