Avatar of BrianM_AZ
BrianM_AZ
 asked on

Create UNICODE file using MFC/C++

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
C++Microsoft DevelopmentProgramming

Avatar of undefined
Last Comment
jkr

8/22/2022 - Mon
jkr

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

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

BrianM_AZ

ASKER
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.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
jkr

>>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

ASKER CERTIFIED SOLUTION
jkr

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
BrianM_AZ

ASKER
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!
BrianM_AZ

ASKER
Thanks for the help!
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
jkr

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