多字节字符下用CFile::Wirte写入文件的代码,在unicode下将strlen改为wcslen,发现写入文件乱码,改为CStdioFile::WriteString写入文件时,发现两行文本中间空一行。
代码显示如下:
void CMainFrame::OnWrite2()
{
// TODO: 在此添加命令处理程序代码
CFile file(L"11.txt", CFile::modeCreate | CFile::modeWrite);
CString str ;
str.Format(L"%s,%s", L"1234567", L"2345678");
str = str + L"\r\n";
file.Write(str, wcslen(str));
str.Format(L"%s,%s", L"3456789", L"4567890");
str = str + L"\r\n";
file.Write(str, wcslen(str));
file.Close();
}
void CMainFrame::OnWrite3()
{
// TODO: 在此添加命令处理程序代码
CStdioFile file(L"22.txt", CFile::modeCreate | CFile::modeWrite);
CString str;
str.Format(L"%s,%s", L"1234567", L"2345678");
str = str + L"\r\n";
file.WriteString(str);
str.Format(L"%s,%s", L"3456789", L"4567890");
str = str + L"\r\n";
file.~~WriteString~~ (str);
file.Close();
}
运行结果:
OnWrite2()修改:file.Write(str, wcslen(str)*sizeof(wchar_t));
OnWrite3()修改:str = str + L"\n";
修改后运行:
原因分析:
字符串长度计算:len=strlen(str)*sizeof(char);len=wcslen(str)*sizeof(wchar_t);
一般情况下:char的长度是1, 即sizeof(char) =1, len=strlen(str)*sizeof(char)等价于strlen(str);
宽字符串wchar_t中wcslen(str)*sizeof(wchar_t)并不等于wcslen(str);
即strlen可直接作为字符串的长度。而使用wcslen得出的不是字符串的长度而是字符的个数。
参考:https://blog.csdn.net/aylixuan/article/details/6130820
virtual void WriteString(LPCTSTR lpsz);
lpsz:指定指向包含 null 终止字符串的缓冲区的指针。
终止字符 null (\0)不会写入文件。 此方法将lpsz中的换行符写入文件,作为回车换行对。(MSDN中解释)
疑问:
如何理解回车换行对?是"\r\n"?还是指"\r"?从程序的运行结果看,文件中自动写入了"\r"。\r 回车 \n 换行。
(英文原文:The terminating null character ( \0) is not written to the file. This method writes newline characters in lpsz to the file as a carriage return-line feed pair.)
另外:
setlocale(LC_ALL, "chs");// 必须设置语言环境,否则 file.WriteString不能输出中文