Ⅰ. やりたいこと
ファイルを読み込み、コンソールに日本語をキレイに出力したいです。
以下の画像が理想の出力です。
Ⅱ. 発生している問題
- ファイル形式が
UTF-8
の場合
文字化けしてしまいます。
abc 縺 ゅ > 縺 ・ ∴ 縺
- ファイル形式が
Shift-JIS
の場合
日本語が表示されますが文字と文字の間に半角スペースと思われるものが入っています。
本当に半角スペースなのかは分かっていません。
aiueo あ い う え お
Ⅲ. プログラム
- test.txt
abc あいうえお
- Source.cpp
cpp
1int main() 2{ 3 // ファイルをすべて読み込む 4 ifstream ifs("test.txt"); 5 string str((istreambuf_iterator<char>(ifs)), istreambuf_iterator<char>()); 6 7 // 出力する 8 cout << str << endl; 9 10 return 0; 11}
Ⅳ. 試したこと
setlocale(LC_ALL, "ja_JP.UTF-8");
変化なし
std::wcout.imbue( std::locale( "", std::locale::ctype ) );
変化なし
setlocale( LC_CTYPE, "" );
変化なし
wchar_t
にする
変化なし
cpp
1wifstream ifs("test.txt"); 2wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 3wcout << str << endl;
Ⅴ. 環境
- Windows 10 64bit Version 1703
- Visual Studio 2017 (v141)
以下のような質問にはグッドを送りましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 間違っている
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答3件
2
自己解決
Shift-JIS
cpp
1#include <iostream> 2#include <fstream> 3#include <string> 4 5ifstream ifs("shift-jis.txt"); 6string str((istreambuf_iterator<char>(ifs)), istreambuf_iterator<char>()); 7 8cout << str << endl;
UTF-8(BOMなし)
cpp
1#include <iostream> 2#include <fstream> 3#include <string> 4#include <codecvt> 5 6setlocale(LC_ALL, ""); 7 8wifstream ifs("UTF-8N.txt"); 9ifs.imbue(locale(locale::empty(), new codecvt_utf8<wchar_t>)); 10wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 11 12wcout << str << endl;
UTF-8(BOMあり)
cpp
1#include <iostream> 2#include <fstream> 3#include <string> 4#include <codecvt> 5 6setlocale(LC_ALL, ""); 7 8wifstream ifs("UTF-8(BOM).txt"); 9ifs.imbue(locale(locale::empty(), new codecvt_utf8<wchar_t, 0x10ffff, consume_header>)); 10wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 11 12wcout << str << endl;
UTF-16 リトルエンディアン (BOMなし)
cpp
1#include <iostream> 2#include <fstream> 3#include <string> 4#include <codecvt> 5 6setlocale(LC_ALL, ""); 7 8wifstream ifs("UTF-16LEN.txt"); 9ifs.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t, 0x10ffff, little_endian>)); 10wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 11 12wcout << str << endl
UTF-16 リトルエンディアン (BOMあり)
cpp
1#include <iostream> 2#include <fstream> 3#include <string> 4#include <codecvt> 5 6setlocale(LC_ALL, ""); 7 8wifstream ifs("UTF-16LE(BOM).txt"); 9ifs.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t, 0x10ffff, consume_header>)); 10wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 11 12wcout << str << endl;
UTF-16 ビッグエンディアン (BOMなし)
cpp
1#include <iostream> 2#include <fstream> 3#include <string> 4#include <codecvt> 5 6setlocale(LC_ALL, ""); 7 8wifstream ifs("UTF-16BEN.txt"); 9ifs.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t>)); 10wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 11 12wcout << str << endl;
UTF-16 ビッグエンディアン (BOMあり)
cpp
1#include <iostream> 2#include <fstream> 3#include <string> 4#include <codecvt> 5 6setlocale(LC_ALL, ""); 7 8wifstream ifs("UTF-16BE(BOM).txt"); 9ifs.imbue(locale(locale::empty(), new codecvt_utf16<wchar_t, 0x10ffff, consume_header>)); 10wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 11 12wcout << str << endl;
投稿2017/05/02 02:38
編集2017/05/02 03:07総合スコア769
1
Win10(1703)+VS2017で再現しました。
プロジェクトの文字セットはデフォルトの「Unicode文字セットを使用する」です。
よって、setlocale
ではなく_tsetlocale
を呼び出すことで、こちらの環境では解消しました。
文字セットを切り替えないなら_wsetlocale
でも良いはずです。
追試
setlocale
,_tsetlocale
,_wsetlocale
のいずれかを呼び出すと、こちらの環境では解消しました。
いずれも呼び出さないと再現します。
C++
1#include <iostream> 2#include <fstream> 3#include <string> 4using namespace std; 5int main() 6{ 7 _tsetlocale(LC_ALL, _T("")); 8 9 // ファイルをすべて読み込む 10 ifstream ifs(_T("test.txt")); 11 string str((istreambuf_iterator<char>(ifs)), istreambuf_iterator<char>()); 12 // 出力する 13 cout << str << endl; 14 return 0; 15}
投稿2017/05/02 00:49
編集2017/05/02 02:34総合スコア36356
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
1
こんにちは。
ファイル形式がShift-JIS の場合
日本語が表示されますが文字と文字の間に半角スペースと思われるものが入っています。
本当に半角スペースなのかは分かっていません。
手元ではShift-JISなら文字化けしないし、文字と文字の間もあきませんでした。原理的にもShift-JISで入力し、Shift-JISで出力すれば文字化けしない筈です。test.txtの内容を確認されて見て下さい。
text
1abc 2あいうえお
wchar_tを使うならば、test.txtをUTF-16のリトルエンディアンで保存すれば文字化けしないはずです。
なぜなら、C++は自動的な文字コード変換には対応していません。
そして、Visual C++のwstringはUTF-16がデフォルトですので、UTF-16で保存しておけば適切に動作する筈です。
なお、この場合はstd::wcout.imbue(std::locale(""));
が必要です。
先週、この辺の問題について記事を書きました。文字コードとVisual C++の悩み
もし、良かったら参考にして下さい。
【追記】
気になるので、wifstreamの動きをみてみました。
下記プログラムでUTF-16LEファイルを読ませると、wstringの1文字にファイル上の1バイトが読み出されていました。MinGW、および、ubuntu上のg++でも同様でした。
何も指定しない場合は、テキスト・ファイルがASCIIでエンコードされていると解釈して読み取る仕様のようです。
C++
1#include <fstream> 2#include <iostream> 3#include <string> 4#include <iomanip> 5using namespace std; 6 7int main() 8{ 9 setlocale(LC_ALL, ""); 10 wifstream ifs("test3.txt"); 11 wstring str((istreambuf_iterator<wchar_t>(ifs)), istreambuf_iterator<wchar_t>()); 12 wcout << str << endl; 13 14 wcout << endl << str.size() << endl; 15 for (auto i : str) 16 wcout << hex << (int)i << "\n"; 17 18 return 0; 19}
投稿2017/05/01 14:44
編集2017/05/02 03:33総合スコア23251
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
関連した質問
Q&A
解決済
Raspberry Pi Pico のC++コードに std::cin を入れると認識しなくなる
回答1
クリップ0
更新
2023/01/30
Q&A
解決済
const char*とchar*の互換性
回答3
クリップ1
更新
2018/03/22
Q&A
解決済
[opengl] ライブラリ制作 ウインドウコンテキストの適切な持たせ方が知りたい。
回答2
クリップ0
更新
2022/11/01
Q&A
解決済
コンソールに日本語をキレイに出力したい
回答3
クリップ3
更新
2017/05/01
Q&A
解決済
C++において,文字列リテラルから 'char*型' への変換が非推奨? エラーメッセージ
回答2
クリップ1
更新
2015/05/10
Q&A
解決済
C++のstring型でキーボード入力の日本語が文字化けする理由
回答1
クリップ0
更新
2023/01/30
Q&A
解決済
Visual Studio CodeのC++にてtxtファイルの読み込みができない
回答1
クリップ0
更新
2023/01/04
Q&A
解決済
VScode,C++にてファイル操作ができない
回答2
クリップ0
更新
2023/01/03
同じタグがついた質問を見る
Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。
C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2017/05/02 02:49 編集