日本語パスのファイルを開き、その内容を出力する方法 – プログラミング – Home

日本語パスのファイルを開き、その内容を...
 
通知
すべてクリア

[解決済] 日本語パスのファイルを開き、その内容を出力する方法


guicheng
 guicheng
(@guicheng)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

環境: Win2000(SP4) VC++2005

下記のフォーラムを参考にして VC2005 でファイルを読み込み、その内容を表示するプロ
グラムを作成しました。
しかし正しく表示させることができず、困っております。

参考: http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=243152&SiteID=7

下記のプログラムを実行すると、123456 とだけ表示され、それ以降の日本語部分は表
示されません。
デバッガで追ってみたところ、ostream の << 演算子の処理で日本語部分が bad_bit と
判定されてしまったために表示されない模様です。

locale の設定をしなければ std::cout に日本語を出力することができますが、この場合
は ifstream を開くことができません。

以上は文字セットを Unicode 、マルチバイトのいずれにしても同様の結果になりました。

cahr* 型の日本語を含むパスでファイルを開き、さらに日本語をコンソール出力する方法
をご存知の方がおられましたら、ご教示ください。

-----------------------------------------------
#include <fstream>
#include <iostream>
#include <string>
#include <locale>

int _tmain(int argc, _TCHAR* argv[])
{
std::locale::global( std::locale( japanese ) );

const char* path = C:\\サンプル\\sample.txt;

std::cout << File open: ;
std::ifstream file_stream( path );
std::cout << file_stream.is_open() << std::endl;

std::string buffer;
while( std::getline( file_stream, buffer ) )
{
std::cout << buffer << std::endl;
}

return 0;
}

// 以下、C:\サンプル\sample.txt の内容
123456サンプル


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

なんか見たことあるぞ。

cout.imbue(locale(japanese));

とするとどうでしょうか?

類似スレ
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=250724&SiteID=7


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

ん、ちがった。

>参考: http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=243152&SiteID=7
で私(蒼の洞窟)も書いていますが、

file_stream.imbue(std::locale(japanese));

ですかね。


返信引用
guicheng
 guicheng
(@guicheng)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

Blue さん、ご回答いただきありがとうございます。

cout と file_stream の両方、またはどちらか一方に imbue(locale(japanese))
を設定しても、やはり結果は同じでした。

しかし、 locale::global を設定せずにファイルのパスを wchar_t* で与えてやると、
想定通りの出力を得られました。
# これって、標準規格にはない使い方のような……

「類似スレ」に書かれているとおり、バグなんでしょうか。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>std::locale::global( std::locale( japanese ) );
をなしで、

>cout と file_stream の両方、またはどちらか一方に imbue(locale(japanese))
>を設定
でも同じ結果でしたでしょうか?


返信引用
guicheng
 guicheng
(@guicheng)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

std::locale::global( std::locale( japanese ) ); を削除した場合、
ファイルストリームを開くことができませんでした。
これは、ファイルストリームのロケール設定をした後で open() しても同様です。

また cout に対する文字列出力に絞って検証してみましたが、locale::global()
があると日本語が表示されず、これを削除した場合は imbue() 関数を使用するしない
に関わらず正常に出力されました。

余談ですが、デバッガで追いかけてみたところ、 locale::global() があれば
file_stream に imbue() しなくとも getline() で正しく文字列を読み込むことが
できるようです。

念のため、今回の検証で使用したコードも掲載しておきます。

-----------------------------------------------------
#include <fstream>
#include <iostream>
#include <string>
#include <locale>

int _tmain(int argc, _TCHAR* argv[])
{
// std::locale::global( std::locale( japanese ) ); //<- グローバルなロケール設定
std::cout.imbue( std::locale( japanese ) ); //<- 標準出力のロケール設定
const char* path = C:\\サンプル\\sample.txt;

std::cout << File open: ;
std::ifstream file_stream;
file_stream.imbue( std::locale( japanese ) ); //<- ファイルストリームのロ
ケール設定
file_stream.open( path );
std::cout << file_stream.is_open() << std::endl;

std::string buffer;
while( std::getline( file_stream, buffer ) )
{
std::cout << buffer << std::endl;
}
file_stream.close();

return 0;
}


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=250724&SiteID=7
結局VC2005のバグのようです。(SP1でも改善されていないっぽい。)

リンク先に書いてあるように、

_setmode(_fileno(stdout), _O_BINARY);

とすることで、std::locale::global() をしても日本語が出力されるようになりました。
(こんどは改行の問題がありますが。)


返信引用
isshi
 isshi
(@isshi)
ゲスト
結合: 21年前
投稿: 41
 

> http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=250724&SiteID=7
あら、Blueさんがすでに挙げてましたね。
失礼しました。


返信引用
guicheng
 guicheng
(@guicheng)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

isshi さん、ご回答ありがとうございます。
私の方でも、

_setmode(_fileno(stdout), _O_BINARY);

とすることで日本語が正しく出力されることを確認しました。
改行コードの問題は運用で回避できそうですので、この方法で対処したいと思います。

また Blue さんもお付き合いいただき、ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました