Create UNICODE file using MFC/C++

BrianM_AZ
BrianM_AZ used Ask the Experts™
on
How do I create a UNICODE encoded file using MFC? It appears that CStdioFile only encodes in ANSI. When I try to "WriteString" it fails.

FILE *fStream;
errno_t err;
err = _tfopen_s( &fStream, _T("test.txt"), _T("w+ ,ccs=UNICODE") );
if( err == 0 )
{        
     CStdioFile f(fStream);
     f.WriteString( _T("TestLine") );
     f.Close();
}

Open in new window

Thanks for the help
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
jkr
Top Expert 2012

Commented:
If your project is set to compile as UNICODE, that should work. But, why are you using a CStdioFile at all since you are already using a file descriptor? You could just use

FILE *fStream;
errno_t err;
err = _tfopen_s( &fStream, _T("test.txt"), _T("w+ ,ccs=UNICODE") );
if( err == 0 )
{        
     _ftprintf(_T("TestLine"));
}
                                  

Open in new window

jkr
Top Expert 2012

Commented:
Ooops, sorry, that should have been

FILE *fStream;
errno_t err;
err = _tfopen_s( &fStream, _T("test.txt"), _T("w+ ,ccs=UNICODE") );
if( err == 0 )
{        
     _ftprintf(fStream,_T("TestLine"));
}
                                  
                                            

Open in new window

Author

Commented:
Unfortunately my project is not setup to compile as UNICODE. All I’m trying to do is create a UNICODE text file to be used by another process.

I used CStdioFile because I’m more familiar with its usage.  I tried your idea but even fprintf validates that the stream is ANSI so it also asserts.
Success in ‘20 With a Profitable Pricing Strategy

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

jkr
Top Expert 2012

Commented:
>>Unfortunately my project is not setup to compile as UNICODE

Hm, then the above should not even compile, but that explains why you won't get a UNICODE text file. But, you could just use STL classes or the CRT to write such a file, e.g.

// STL
#include <fstream>
using namespace std;

// ...

wofstream wos("test.txt");

wos << L"UNICODE text";

Open in new window


// CRT

#include <stdio.h>
#include <wchar.h>

FILE* p = _wfopen(L"test.txt".L"wt+,ccs=UNICODE");

fwprintf(p,L"%s",L"UNICODE text");

fclose(p);

Open in new window

Top Expert 2012
Commented:
BTW, CFile would do the trick as well:

CFile out("test.txt",CFile::modeWrite);
wchar_t acText[] = L"UNICODE text";

out.Write(acText,wcslen(acText));

Open in new window

Author

Commented:
Using CFile seems to be the ticket! I have one more question I hope you don't mind answering...
Here's my code -
CFile file("test.txt", CFile::modeCreate | CFile::modeWrite);
CStringW sOutStr = "Test output string";
file.Write( sOutStr, wcslen(sOutStr.GetBuffer()) * 2 );

Open in new window

Why do I have to double the string length? I would think that because I'm using CStringW it would be correct using file.Write( sOutStr, wcslen(sOutStr.GetBuffer()) );

Thanks!

Author

Commented:
Thanks for the help!
jkr
Top Expert 2012

Commented:
Aw, my fault - 'wcslen()' returns the amount of characters in a UNICODE string, yet a single character is two bytes, that's why.

The 'pedantically' correct way would be to

file.Write( sOutStr, wcslen(sOutStr.GetBuffer()) * sizeof(wchar_t) );

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial