wcslen,WriteString写入文件问题

多字节字符下用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();
}

运行结果:
wcslen,WriteString写入文件问题_第1张图片
OnWrite2()修改:file.Write(str, wcslen(str)*sizeof(wchar_t));
OnWrite3()修改:str = str + L"\n";
修改后运行:
wcslen,WriteString写入文件问题_第2张图片

原因分析:

  1. CFile::Wirte

字符串长度计算: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

  1. CStdioFile::WriteString

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不能输出中文

你可能感兴趣的:(C++)