printfの使い方がぶっ飛んでるのはすでに指摘があるのでこれ以上触れないこととして本題。
C++で、またWindowsで動かすコンソールアプリケーションで適切に文字を取り扱うのは容易ではありません。
これは歴史的経緯もあります。
ref: C++標準化委員会、ついに文字とは何かを理解する: char8_t
Windows のコンソールアプリケーションは何もしないとシステムロケールで動作します。お使いの環境が日本語環境ならcp932(Shift-JIS)という文字コードで表示されます。つまりcp932(Shift-JIS)に含まれない文字(絵文字とかその他多数)を表示しようとすれば表現できませんから文字化けのように見えます。
またそもそもお示しのコードには文字コード変換部分が見受けられません。つまり、読み込んだテキストファイルの文字コードがシステムロケール(多分cp932)と一致しなければ文字化けします。
例えば読み込んだテキストがUTF-8でエンコードされていた場合、cp932とUTF-8でたまたま同じようにエンコードされる範囲(いわゆるASCII)以外は文字化けするでしょう。
読み込んだテキストがUTF-8でエンコードされていた場合にソースコードに手を加えず文字化けを防ぐ方法は最近まではありませんでしたが、Windows 10 1607以降ではchcp 65001
とすることでプログラムが動作するロケールをcp932からUTF-8に切り替えられます(正確には昔からあったけどフォントが正しく設定できなかったので実質使えなかった)。chcp 65001
の代わりに同等Win32API(SetConsoleCP
)を叩いてもいいですが。ただし実行前にフォント設定をお忘れなく。
読み込んだテキストがUTF-8でエンコードされていた場合、こうすれば読み込んだテキストと動作環境のロケールが一致するので文字化けしなくなります。
それ以外のケースでは文字コード変換を行う必要がありますが、これはC/C++標準の範囲ではできず(C++11で追加されたもののC++17でdeprecatedになったため使えない)、Win32APIに頼る必要があります。ただしいかに変換しようともwchar_t
系のAPIを叩こうと、コンソールアプリケーションで標準出力から出す限り最終的にシステムロケールの文字コードに内部で変換されますのでcp932で表わせない文字はchcp 65001
相当のことをしなければ表現できないことに変わりはありません。
いずれにせよWindowsのコンソールアプリケーションで適切に文字を扱うのは依然として容易ではないのでときには諦めるほうが良かったりします。もしくはコンソールアプリケーションではなくGUIアプリケーションを作るほうが融通がききます。
C++側ではUTF-8でエンコードされた文字を格納することを意図したchar8_t
型が追加され、WindowsのいわゆるA系APIもUTF-8に対応するようになりつつあります。あと10年位したらすべてがUTF-8な時代が来てこの辺が楽になるといいですね。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/07 06:45
2019/12/07 06:51