C++ 使用Write成员将CString写入CFile时,每个字符后都为null
我目前正在学习MFC库CFile类,我在使用Write方法将数据写入文件时遇到了一个问题。当我将char数组作为参数传递时,它工作得非常好:C++ 使用Write成员将CString写入CFile时,每个字符后都为null,c++,mfc,C++,Mfc,我目前正在学习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());
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();
但输出与上面相同。是什么导致了这种转变?这是因为文本存储在宽字符中吗?这是因为您在编译时定义了
UNICODE
,而CString
是一个宽字符字符串,每个宽字符占用两个字节。写入文件的是字符字节,后跟零字节。这是因为编译时定义了UNICODE
,而CString
是一个宽字符字符串,每个字符占用两个字节。你的文件中所写的是字符字节,后面是零字节。 < P>我在MFC、Visual C++ 6到Visual C++ 2005中开发了大约4年,现在专业地支持我们的公司应用。
根据我的经验和我对CString
类对象的了解,它们总是NULL
终止。这可能会导致与使用字符数组不同的行为,但不是上述问题
我相信您的问题与您作为参数传递的缓冲区有关LPWSTR
是一个32位指针,指向一个由16位字符组成的字符串
据我所知,根据您发布的内容,您正在输出16位Unicode
字符,并将其视为ANSI
,因此这种行为是意料之中的。如果将记事本文件作为Unicode打开,则不会看到空格
或者,如果您使用
ANSI
字符集构建项目,或者在写入文件之前将其转换为ANSI
,则在记事本中打开输出时,空格应消失。我一直在MFC中开发,Visual C++ 6到Visual C++ 2005大约有4年的时间,现在专业地支持我们的公司应用。
根据我的经验和我对CString
类对象的了解,它们总是NULL
终止。这可能会导致与使用字符数组不同的行为,但不是上述问题
我相信您的问题与您作为参数传递的缓冲区有关LPWSTR
是一个32位指针,指向一个由16位字符组成的字符串
据我所知,根据您发布的内容,您正在输出16位Unicode
字符,并将其视为ANSI
,因此这种行为是意料之中的。如果将记事本文件作为Unicode打开,则不会看到空格
或者,如果您使用
ANSI
字符集构建项目,或者在写入文件之前将其转换为ANSI
,则在记事本中打开输出时,空格应消失。问题:
第二个参数是函数将从第一个参数(缓冲区)传输的字节数。您正在传递的是cS.GetLength()
,它更愿意传递字符串中的字符数,而这与字符串本身可能包含的字节数不同
解决方案:
您应该将将将字符串写入文件的行更改为以下内容:
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
CString cS(_T("Hello"));
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
sizeof(TCHAR)
将根据您是构建Unicode还是MBCS生成不同的数字。这是因为TCHAR
对于Unicode构建被定义为wchar\t
,对于MBCS构建被定义为char
。因此,无论您是否构建Unicode,将字符串的长度乘以TCHAR的大小始终等于由字符串组成的字节数
需要注意的其他要点:
你没有理由在这里调用GetBuffer()
和ReleaseBuffer()
这一点不是主要的,但是CFile::Write
函数将const void*
作为其第一个参数。因此,您应该将CString
强制转换为LPCTSTR
(如果使用Unicode或MBCS构建,则会自动计算为LPCWSTR
或LPCSTR
)
最后一件事:最好使用\u T()
宏包装字符串文本,这样您就可以编译Unicode和MBCS,而无需更改代码
应用所有更改,您的整个代码将如下所示:
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
CString cS(_T("Hello"));
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
问题: 第二个参数是函数将从第一个参数(缓冲区)传输的字节数。您正在传递的是
cS.GetLength()
,它更愿意传递字符串中的字符数,而这与字符串本身可能包含的字节数不同
解决方案:
您应该将将将字符串写入文件的行更改为以下内容:
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
CString cS(_T("Hello"));
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
sizeof(TCHAR)
将根据您是构建Unicode还是MBCS生成不同的数字。这是因为TCHAR
对于Unicode构建被定义为wchar\t
,对于MBCS构建被定义为char
。因此,无论您是否构建Unicode,将字符串的长度乘以TCHAR的大小始终等于由字符串组成的字节数
需要注意的其他要点:
你没有理由在这里调用GetBuffer()
和ReleaseBuffer()
这一点不是主要问题,但是CFile::Write
函数采用常量void*