Reputation: 719
First off: I know there are similar topics for C++, but I am curious about standard C, and I don't believe my problem is related to previous problems.
I am trying to implement Unicode support for a simple program which just asks the user to select a directory through a folder browser and then passes it to another program (only got to the first part). But when attempting to write the received path to a file, it results in a 0-byte file. And when printing it out using wprintf_s
, non-ASCII characters come out as question marks. I don't believe there is any undefined behavior or anything as I've double checked documentation. So what am I doing wrong?
The code currently looks like this (just the bare minimum for strict test conditions):
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
int main()
{
BROWSEINFOW bi = { 0 };
LPITEMIDLIST pidl;
wchar_t path[MAX_PATH];
pidl = SHBrowseForFolderW(&bi);
SHGetPathFromIDListW(pidl, path);
wprintf_s(L"%s\n", path);
return 0;
}
The above code prints it regularly. When attempting to write to a file instead, I replace the wprintf_s
call with this (having declared FILE *f
first of course):
if(_wfopen_s(&f, L"C:\\test.txt", L"w"))
{
fwprintf_s(f, L"%s\n", path)
fclose(f);
}
However, I have also tried using fwrite
with both w
and wb
mode, but all methods results in an empty file.
Upvotes: 2
Views: 995
Reputation: 31599
You need _O_U16TEXT
for console output, and "UTF-16LE"
for file output.
Also, _wfopen_s
returns zero when successful according to MS documentation:
Return Value Zero if successful; an error code on failure. See errno, _doserrno, _sys_errlist, and _sys_nerr for more information about these error codes.
You should make sure return value is zero
if (0 == _wfopen_s(&f, filename, L"w, ccs=UTF-16LE")){
//isokay ...
}
or check if f
is non-NULL. For example:
#include <stdio.h>
#include <io.h> //for _setmode
#include <fcntl.h> //for _O_U16TEXT
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
const wchar_t *buf = L"ελληνική";
wprintf(L"%s\n", buf);
FILE *f = NULL;
_wfopen_s(&f, L"C:\\test\\test.txt", L"w, ccs=UTF-16LE");
if (f)
{
fwprintf_s(f, L"%s\n", buf);
fclose(f);
}
return 0;
}
Upvotes: 2