WriteFileでWCHARを書き込む方法とか - かせきのうさぎさん

WriteFileでWCHARを書き込む方法とか

ワイド文字列を WriteFile() でファイルに書き出してみる。

#define UNICODE

#include <windows.h>
#include <stdio.h>

void test(HANDLE file)
{
    WCHAR s[] = L"あいうえお";
    DWORD written;
    WriteFile(file, s, 5 * sizeof(WCHAR), &written, NULL);
}

int main()
{
    HANDLE file = CreateFile(L"a.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE != file) {
        test(file);
        CloseHandle(file);
    } else {
        puts("IOError");
        return 1;
    }
    return 0;
}

書き込んだファイルをエディタで開くと文字化けしている。文字コードを UTF-16LE に設定して開くとちゃんと見えるので、単にByte Order Mark (BOM) が付いていないだけだとわかる。

こうすればエディタがきちんと自動判定できるようになる。

void test(HANDLE file)
{
    WCHAR s[] = L"\xFEFFあいうえお";
    DWORD written;
    WriteFile(file, s, 6 * sizeof(WCHAR), &written, NULL);
}

以上「WriteFile WCHAR | LPWSTR | PWSTR | wchar_t」とかでググっても出てこないのでメモしておく。

ちなみに OPEN_ALWAYS でファイルに追記する場合、BOM を書き込むかどうか判定する必要が出てくるけど、それはこうすればいいかな。

#define UNICODE

#include <windows.h>
#include <stdio.h>

int main()
{
    HANDLE file = CreateFile(L"c.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == file) {
        puts("IOError");
        return 1;
    }

    if (GetLastError() != ERROR_ALREADY_EXISTS) {
        puts("新規ファイルです。");
        
        char bom[2] = {0xFF, 0xFE};
        DWORD written;
        WriteFile(file, bom, 2, &written, NULL);
    } else {
        puts("既存のファイルを開きました。");
        
        SetFilePointer(file, 0, NULL, FILE_END);
    }
    
    
    WCHAR tm[128];
    int cch = GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL, L"hh':'mm':'ss'\r\n'", tm, 128);
    if (cch > 0) {
        DWORD written;
        
        cch --;
        WriteFile(file, tm, cch * sizeof(WCHAR), &written, NULL);
    }
    CloseHandle(file);
    
    return 0;
}

このように CreateFile() が成功していても GetLastError() を使うことがある。


参考