使用Write成员将CString写入CFile时,每个字符后为空

时间:2016-11-17 23:54:02

标签: c++ mfc

我目前正在研究MFC库CFile类,我遇到了使用Write方法将数据写入文件的问题。当我传递char数组作为参数时,它完全正常:

char c[] = "Hello!"; 
int size = sizeof(c) / sizeof(c[0]);
myFile.Write(c, size)

写入文件的字符:

Hello!

但是当我尝试将CS​​tring对象作为参数传递时:

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();

但输出与上面相同。可能导致转换的原因是什么?是否因为文本以宽字符存储而发生?

4 个答案:

答案 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构建,它会自动评估为LPCWSTRLPCSTR

最后一件事:用_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位指针,指向每个enter image description here的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的一半值。

尝试更改您的文字类型的上述代码

https://msdn.microsoft.com/en-us/library/6337eske.aspx