Printing/writingwchar_t?

Printing/writing wchar_t?

首先:我知道 C++ 有类似的主题,但我对标准 C 很好奇,我不认为我的问题与以前的问题有关。

我正在尝试为一个简单的程序实现 Unicode 支持,该程序只要求用户通过文件夹浏览器 select 一个目录,然后将其传递给另一个程序(只到达第一部分)。但是当尝试将接收到的路径写入文件时,它会生成一个 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);
}

不过,我也尝试过在 wwb 模式下使用 fwrite,但所有方法都会生成一个空文件。

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

此外,_wfopen_s return根据 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.

您应该确保 return 值为零

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