打印/写wchar_t?

时间:2016-06-02 20:12:36

标签: c winapi unicode wchar-t

首先:我知道C ++有类似的主题,但我对标准C感到好奇,而且我不相信我的问题与以前的问题有关。

我正在尝试为一个简单的程序实现Unicode支持,该程序只要求用户通过文件夹浏览器选择目录,然后将其传递给另一个程序(仅限第一部分)。但是当尝试将接收到的路径写入文件时,会产生0字节的文件。使用wprintf_s打印时,非ASCII字符作为问号出现。我不相信有任何未定义的行为或任何事情,因为我已经仔细检查了文档。那么我做错了什么?

代码目前看起来像这样(严格测试条件的最低限度):

#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;
}

以上代码会定期打印。在尝试写入文件时,我将wprintf_s调用替换为此(当然首先声明FILE *f):

if(_wfopen_s(&f, L"C:\\test.txt", L"w"))
{
    fwprintf_s(f, L"%s\n", path)
    fclose(f);
}

但是,我也尝试在fwritew模式下使用wb,但所有方法都会产生空文件。

1 个答案:

答案 0 :(得分:2)

控制台输出需要_O_U16TEXT,文件输出需要"UTF-16LE"

此外,_wfopen_s根据MS documentation成功返回零:

  

如果成功则返回零;失败时的错误代码。见errno,   _doserrno,_sys_errlist和_sys_nerr,了解有关这些错误代码的更多信息。

您应该确保返回值为零

if (0 == _wfopen_s(&f, filename, L"w, ccs=UTF-16LE")){
    //isokay ...
}

或检查f是否为非NULL。例如:

#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;
}