Ⅰ. やりたいこと
ファイルを読み込み、コンソールに日本語をキレイに出力したいです。
Ⅱ. 発生している問題
- ファイル形式が
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)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
自己解決
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
0
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総合スコア38352
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
こんにちは。
ファイル形式が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総合スコア23274
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/02 02:49 編集