Windows11 ロケールと NTFS

例によって Windows11 では動くが Windows Server 2016 では動かないシリーズです。

日本語フォルダを含むフォルダ一覧ファイル folderNames.txt があったとします。

C:\日本語フォルダ

Windows11 のメモ帳でこれを保存するとデフォルトは Unicode となります。

従って、以下のプログラムを動かすと、Windows11では普通に動く。

void checkText(const wstring &fname) {
  wstring token;
  wifstream wif(fname);
  while (!getline(wif, token).eof()) {
    if (PathIsDirectory(token.c_str()) {
      wcout << TEXT("Path Found") << endl;
    }
    wcout << token << endl;
  }
} 
Path Found
C:\日本語フォルダ

一方、古い Windows Server ではデフォルト文字コードが ANSI (SJIS) になっているため、正しくPath を見つけることができません。

C:\日本語フォルダ

wcout には普通に出力がされるんですよねえ…

結局これを解決するには、SJIS を Unicode に内部で変換するしかないという結論になりました。

void checkText(const wstring &fname) {
  int slen = WideCharToMultiByte(CP_THREAD_ACP, 0, fname.data(), fname.length(), NULL, 0);
  char *s = new char [slen + 1];
  WideCharToMultiByte(CP_THREAD_ACP, 0, fname.data(), fname.length(), s, slen);
  ifstream ifs(string(s, slen));
  delete[] s;
  string token;
  while (!getline(ifs, token).eof()) {
    int wlen = MultiByteToWideChar(CP_THREAD_ACP, 0, token.data(), token.length(), NULL, 0, NULL, NULL);
    wchar_t* w = new wchar_t[token.length + 1];
    MultiByteToWideChar(CP_THREAD_ACP, 0, token.data(), token.length(), w, wlen, NULL, NULL);
    if (PathIsDirectory(w)) {
      wcout << TEXT("Path is Found") << endl;
    }
    wcout << wstring(w, wlen) << endl;
  }
}

あまり奇麗じゃない。。

投稿者について
みのしす

小さいときは科学者になろうとしたのに、その時にたまたま身に着けたプログラミングで未だに飯を食っているしがないおじさんです。(年齢的にはもうすぐおじいさん)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です