Reputation: 877
I'm currently studying MFC library CFile class and I have a problem with writing data to a file using Write method. When I pass char array as parameter it works perfectly fine:
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:
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?
Upvotes: 0
Views: 1610
Reputation: 780
Problem:
The second parameter to CFile::Write is the number of bytes that the function will transfer from the first parameter (the buffer). 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.
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. This is because TCHAR
is defined as wchar_t
for Unicode builds, and as char
for MBCS builds. 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.
Other points to note:
You've no reason to call GetBuffer()
and ReleaseBuffer()
here, whatsoever.
This point is not a major, but the CFile::Write
function takes a const void *
as its first argument. 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).
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.
Applying all changes, your whole code would look something like this:
CString cS(_T("Hello"));
myFile.Write(LPCTSTR(cS), cS.GetLength()*sizeof(TCHAR));
Upvotes: 3
Reputation: 68
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.
Try changing above code for your type of text
https://msdn.microsoft.com/en-us/library/6337eske.aspx
Upvotes: 0
Reputation: 1
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.
In my experiences and what I know of the CString
class objects, they are always NULL
terminated. 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.
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. If you were to open your notepad file as Unicode
, you would not see the spaces.
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.
Upvotes: 0
Reputation: 32732
That's because you're compiling with UNICODE
defined, and CString
is a string of wide characters, each of which occupies two bytes. What's getting written to your file is what you're seeing as the character byte, followed by a zero byte.
Upvotes: 0