我目前正在研究MFC库CFile类,我遇到了使用Write方法将数据写入文件的问题。当我传递char数组作为参数时,它完全正常:
char c[] = "Hello!";
int size = sizeof(c) / sizeof(c[0]);
myFile.Write(c, size)
写入文件的字符:
Hello!
但是当我尝试将CString对象作为参数传递时:
CString cS("Hello");
myFile.Write(cS, cS.GetLength());
我明白了:
H e l
我也尝试过:
CString cS("Hello");
LPWSTR c = cS.GetBuffer();
myFile.Write(c, cS.GetLength());
cS.ReleaseBuffer();
但输出与上面相同。可能导致转换的原因是什么?是否因为文本以宽字符存储而发生?
答案 0 :(得分:3)
<强>问题:强>
CFile::Write的第二个参数是函数从第一个参数(缓冲区)传输的字节数。您正在传递cS.GetLength()
,它宁可传递字符串中的字符数,这与字符串本身可能构成的字节数不同。
<强>解决方案:强>
您应该将将字符串写入文件的行更改为以下内容:
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
如果您要为Unicode或MBCS构建, sizeof(TCHAR)
将产生不同的数字。这是因为TCHAR
对于Unicode构建定义为wchar_t
,对于MBCS构建定义为char
。因此,将字符串的长度乘以TCHAR的大小总是等于字符串组成的字节数,无论您是否为Unicode构建。
需要注意的其他要点:
您没有理由在此处致电GetBuffer()
和ReleaseBuffer()
。
这一点不是主要的,但CFile::Write
函数将const void *
作为其第一个参数。因此,您应该将CString
转换为LPCTSTR
(根据您是否使用Unicode或MBCS构建,它会自动评估为LPCWSTR
或LPCSTR
。
最后一件事:用_T()
宏包装字符串文字是很好的,这样你就可以编译Unicode和MBCS,而无需更改你的代码。
应用所有更改后,您的整个代码将如下所示:
CString cS(_T("Hello"));
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
答案 1 :(得分:0)
那是因为您正在使用UNICODE
定义进行编译,CString
是一个宽字符串,每个字符占用两个字节。写入文件的内容是您所看到的字符字节,后跟零字节。
答案 2 :(得分:0)
我一直在MFC,Visual C ++ 6.0到Visual C ++ 2005开发大约4年,现在已经专业地支持我们公司的应用程序。
根据我的经验和我对CString
类对象的了解,它们总是NULL
终止。这可能会导致与使用字符数组不同的行为,但不是上面的问题。
我相信你的问题与你作为参数传递的缓冲区有关。 LPWSTR
是一个32位指针,指向每个的16位字符串。
根据您发布的内容,我可以输出16位Unicode
个字符并将其视为ANSI
,因此可以预期这种行为。如果您以Unicode
打开记事本文件,则不会看到空格。
或者,如果您使用ANSI
字符集构建项目,或在写入文件之前转换为ANSI
,则在记事本中打开输出时空格应该消失。
答案 3 :(得分:0)
试试这个
TCHAR c[] = "Hello!";
int charCount = sizeof(c) / sizeof(c[0]);
myFile.Write(c, charCount*sizeof(c[0]));
写入将只写入指定的字节数。 charCount将与ASCII的字节数相同,但是将是UNICODE的一半值。
尝试更改您的文字类型的上述代码