简体   繁体   English

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

[英]Nulls after each character when writing CString to CFile using Write member

I'm currently studying MFC library CFile class and I have a problem with writing data to a file using Write method. 我目前正在研究MFC库CFile类,并且在使用Write方法将数据写入文件时遇到问题。 When I pass char array as parameter it works perfectly fine: 当我将char数组作为参数传递时,它可以正常工作:

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

Characters that were written to file: 写入文件的字符:

Hello!

But when I try to pass CString object as an argument: 但是,当我尝试将CS​​tring对象作为参数传递时:

CString cS("Hello");
myFile.Write(cS, cS.GetLength());

I get: 我得到:

H e l

I also tried: 我也尝试过:

CString cS("Hello");
LPWSTR c = cS.GetBuffer();
myFile.Write(c, cS.GetLength());
cS.ReleaseBuffer();

But the output is the same as above. 但是输出与上面相同。 What may be cause that conversion? 是什么原因导致转换? Does it happen because text is stored in wide characters? 是否因为文本以宽字符存储而发生?

Problem: 问题:

The second parameter to CFile::Write is the number of bytes that the function will transfer from the first parameter (the buffer). CFile :: Write的第二个参数是函数将从第一个参数(缓冲区)传输的字节数。 You're passing cS.GetLength() , which would rather pass the number of characters in the string, and this is not the same as the number of bytes that the string itself may be composed of. 您正在传递cS.GetLength() ,它更愿意传递字符串中的字符数,这与字符串本身可能组成的字节数不同。

Solution: 解:

You should change the line that writes the string into file to something like this: 您应该将将字符串写入文件的行更改为如下所示:

myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));

sizeof(TCHAR) will yield a different number based on if you're building for Unicode or MBCS. 如果您要为Unicode或MBCS构建, sizeof(TCHAR)将产生不同的数字。 This is because TCHAR is defined as wchar_t for Unicode builds, and as char for MBCS builds. 这是因为对于Unicode构建, TCHAR被定义为wchar_t ,对于MBCS构建, TCHAR被定义为char As such, multiplying the length of string with the size of TCHAR will always equal the number of bytes the string is composed of regardless of if you're building for Unicode or not. 因此,将字符串的长度乘以TCHAR的大小将始终等于组成字符串的字节数,而不管是否要为Unicode构建。

Other points to note: 其他注意事项:

You've no reason to call GetBuffer() and ReleaseBuffer() here, whatsoever. 您没有理由在这里调用GetBuffer()ReleaseBuffer()

This point is not a major, but the CFile::Write function takes a const void * as its first argument. 这一点不是主要问题,但是CFile::Write函数将const void *作为其第一个参数。 So you should rather be casting your CString to LPCTSTR (which would automatically evaluate to LPCWSTR or LPCSTR based on if you're building with Unicode or MBCS). 因此,您应该将CString强制转换为LPCTSTR (如果您使用Unicode或MBCS构建,它将自动评估为LPCWSTRLPCSTR )。

One last thing: It's good to wrap string literals with the _T() macro so that you could compile for Unicode and MBCS alike without having to change your code. 最后一件事:用_T()宏包装字符串文字是很好的,这样您就可以像Unicode和MBCS一样进行编译,而不必更改代码。

Applying all changes, your whole code would look something like this: 应用所有更改,您的整个代码将如下所示:

CString cS(_T("Hello"));
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));

That's because you're compiling with UNICODE defined, and CString is a string of wide characters, each of which occupies two bytes. 那是因为您正在使用定义的UNICODE编译,并且CString是一串宽字符,每个字符占用两个字节。 What's getting written to your file is what you're seeing as the character byte, followed by a zero byte. 写入文件的是字符字节,后跟零字节。

I have been developing in MFC, Visual C++ 6.0 to Visual C++ 2005 for about 4 years now professionally to support our companies applications. 我已经在MFC,Visual C ++ 6.0到Visual C ++ 2005的开发领域进行了大约4年的专业开发,以支持我们公司的应用程序。

In my experiences and what I know of the CString class objects, they are always NULL terminated. 根据我的经验以及对CString类对象的了解,它们始终以NULL终止。 This can cause different behavior than using a character array, but is not the problem above. 与使用字符数组相比,这可能导致不同的行为,但这不是上面的问题。

I believe your problem to be related to the buffer you are passing in as an argument. 我相信您的问题与作为参数传递的缓冲区有关。 LPWSTR is a 32-bit pointer to a string of 16-bit characters per this MSDN Reference . LPWSTR是此MSDN Reference指向一个16位字符的字符串的32位指针。

From what I can tell based on what you posted, you are outputting 16 bit Unicode characters and viewing them as ANSI hence this behavior would be expected. 根据我发布的内容,您正在输出16位Unicode字符,并将其视为ANSI因此可以预期会出现这种情况。 If you were to open your notepad file as Unicode , you would not see the spaces. 如果要以Unicode打开记事本文件,则不会看到空格。

Alternatively, if you build your project using ANSI character set, or convert to ANSI prior to writing to the file, the spaces should go away when you open the output in notepad. 另外,如果您使用ANSI字符集构建项目,或者在写入文件之前转换为ANSI ,则在记事本中打开输出时,空格应消失。

try this 尝试这个

TCHAR c[] = "Hello!"; 
int charCount = sizeof(c) / sizeof(c[0]);
myFile.Write(c, charCount*sizeof(c[0]));

Write will write only number of bytes specified. 写操作将只写指定的字节数。 charCount will be same as number of bytes for ASCII, but will be half the value for UNICODE. charCount将与ASCII的字节数相同,但将为UNICODE的值的一半。

Try changing above code for your type of text 尝试为您的文本类型更改以上代码

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM