前回はみなさん沢山コメントくださってありがとうございます。
わたくしあれからいろいろと実験してみまして。
いろいろテストやってみて、どうやらVSさんはコンパイル時に文字列リテラルをShift-JISに変換してて、ついでに日本語版WindowsコンソールウィンドウはShift-JISがデフォルトなんだなってことがわかりました。…ってところまでは良いのですが、じゃあutf-8のファイル扱いたいときとかどうすんだよって話ですよ。ユーザーが用意したファイルの文字コードを判別して変換して、さらにユーザーのコンソールウィンドウの現在の文字コードを調べてそれに変換して出力なんてのをやる必要があるとかどんだけめんどくさいんですか。まあ、日本人開発者は日本人にだけソフト配布してりゃいいんだよって考えなのでしょう。utf-8以外の文字コードが全て滅びれば楽になるのに。ついでに世界中の言語が英語とSwiftだけになればもっと楽で素敵な世界がおっと誰か来たようだ。
コンパイル時の文字列リテラルを指定できないのか?と思って調べてみると、
それっぽい内容を扱っているサイトを見つけました。
どうやら
「Unicode文字セットを使用する」を選択した場合:
・Windows.hとかの関数はWの方が選択されるようになる
・TCHAR, tstring, _T()などのマクロはワイド文字の方が選択されるようになる
・コンパイル時、文字列リテラルはutf-16に変換される
「マルチバイト文字セットを使用する」を選択した場合:
・Windows.hとかの関数はAの方が選択されるようになる
・TCHAR, tstring, _T()などのマクロはマルチバイト文字の方が選択されるようになる
・コンパイル時、文字列リテラルはShift-JISに変換される
ということらしい。
実験を3つ行ってみました。
準備したファイル
Shift-JIS
ソースコード
► スポイラーを表示
CODE:
#include
#include
#include
int main()
{
std::ifstream ream("Shift-JIS.txt");
const int bufsize = 256;
char buf[bufsize];
std::cout
#include
#include
int main()
{
std::wifstream ream(L"utf-16.txt");
const int bufsize = 256;
wchar_t buf[bufsize];
std::wcout
#include
#include
#pragma execution_character_set("utf-8")
int main()
{
std::ifstream ream("utf-8.txt");
const int bufsize = 256;
char buf[bufsize];
std::cout << "alphabet:" << std::endl;
std::string alphabet("alphabet");
ream.getline(buf, bufsize);
if (buf == alphabet)
{
std::cout << "matched!" << std::endl;
}
else
{
std::cout << "unmatched..." << std::endl;
std::cout << buf << std::endl;
}
std::cout << "\n日本語:" << std::endl;
std::string japanese("日本語");
ream.getline(buf, bufsize);
if (buf == japanese)
{
std::cout << "matched!" << std::endl;
}
else
{
std::cout << "unmatched..." << std::endl;
std::cout << buf << std::endl;
}
return 0;
}
結果
CODE:
alphabet:
mutched!
vねrf(←文字化け)
mutched!
utf-8で文字化けしてるのはutf-8をShift-JISに変換せずにコンソールに渡してるから当たり前ですね。
ということはうまくいってないのはutf-16のときですね。どうしてでしょうね。
ちなみにBOMありも試してみましたがダメでした。
まあ、ぶっちゃけ文字列リテラルを使わなければいいだけの話なんですけどね!!