ワイド文字列を 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() を使うことがある。