C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: 日本語ファイル名とcoutでマルバイト文字列出力の並存


(過去ログ 54 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■30586 / inTopicNo.1)  日本語ファイル名とcoutでマルバイト文字列出力の並存
  
□投稿者/ dogatana (25回)-(2008/12/27(Sat) 10:17:28)

分類:[C/C++] 

こんにちは

VC++2005でコンソールアプリを作成し、ファイル処理をしています。
ファイル名は main() の引数から取得しているので、
std::ifstream ifs(argv[1]);
としているのですが、ここで No 28731 の問題にぶつかりました。

早速
std::locale::global(std::locale(""));
を main() の先頭に入れたのですが、今度は std::cout << argv[1] とか、
読み込んだ日本語を含む文字列リテラルを std::cout に出力することができなくなって
しまいました。(実行時画面に表示されないという現象)

急ぎだったので、とりあえずBorland C++でコンパイルして回避しましたが、VC++での回避策をご存知の
方がいらっしゃいますでしょうか?

不思議なことに、標準出力がコンソールのままだと日本語は表示されないのですが、ファイルにリダイ
レクションすると内容は正しいですし、パイプで more につなげてやっても正しく表示されます。

引用返信 編集キー/
■30587 / inTopicNo.2)  Re[1]: 日本語ファイル名とcoutでマルバイト文字列出力の並存
□投稿者/ ちゃっぴ (185回)-(2008/12/27(Sat) 11:04:26)
ちゃっぴ さんの Web サイト
VC 2005 では defualt が Unicode で compile されるようになっているので wcout を使うべきでしょう。
引用返信 編集キー/
■30589 / inTopicNo.3)  Re[1]: 日本語ファイル名とcoutでマルバイト文字列出力の並存
□投稿者/ アキラ (142回)-(2008/12/27(Sat) 12:19:58)
アキラ さんの Web サイト
2008/12/27(Sat) 12:21:36 編集(投稿者)
No30586 (dogatana さん) に返信

#include <iostream>

using namespace std;

int main()
{
    std::locale::global(std::locale(""));

    cout << "あいうえお" << endl;
}



VC2005はロケール周りにバグがあるのでそのせいかもしれません。
2005ではcoutでたしかに表示されませんでした。(ロケールの行をなくすと表示される)
2008ではうまくいきました。

引用返信 編集キー/
■30591 / inTopicNo.4)  Re[2]: 日本語ファイル名とcoutでマルバイト文字列出力の並存
□投稿者/ あしび (7回)-(2008/12/27(Sat) 12:44:55)
同じ問題にはまったことのある人間です。
皆さんのおっしゃっていられるようにバグとUnicode関係の混合攻撃でした。
ものすごくいろんなことにはまった末,std:localeではなく、Cのsetlocaleを使うことで回避しました。



引用返信 編集キー/
■30592 / inTopicNo.5)  Re[3]: 日本語ファイル名とcoutでマルバイト文字列出力の並存
□投稿者/ dogatana (26回)-(2008/12/27(Sat) 13:05:11)
ちゃっぴさん、アキラさん、あしびさん、ご助言ありがとうございます。

■No30591 (あしび さん) に返信
> 同じ問題にはまったことのある人間です。
> 皆さんのおっしゃっていられるようにバグとUnicode関係の混合攻撃でした。
> ものすごくいろんなことにはまった末,std:localeではなく、Cのsetlocaleを使うことで回避しました。

状況が
・扱うファイルのデータはシフトJISのデータであること(Unicodeへの変換はちょっと)
・プログラム内の文字列リテラルに、Lをつけて回るのが面倒なこと ^^;
・プログラム内のcoutをwcoutに書き換えるのも面倒なこと ^^;;
・問題はifsreamが受け付けるファイル名だけである(らしい)こと
から、何とか今までのプログラムをそのまま使えないかと色々試したところ
	std::locale::global(std::locale(""));
	std::ifstream ifs(argv[1]);
	std::locale::global(std::locale("C"));
と、ifstreamのインスタンスを生成する前後にロケールの設定を行うことで回避できることがわかりました。
今のところ、問題なく動作してますので、ひとまずこれで進めたいと思います。

ただアキラさんの書き込みを見ると、VC2008に変えるのが一番良さそうですね。

ありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -