none
日本語PATH文字化け RRS feed

  • 質問

  • 初めまして、よろしくお願いします。

    Express C++ 2005で、コンソールアプリを作りました。

    ファイルを出力する処理を行っているのですが、日本語のPATHだと、出力されないか

    文字化けしたファイル名になってしまいます。Win32 SDKが、Englishになっているから

    でしょうか。でも、コンソールに対しての日本語文字列出力は問題有りませんし、

    当然ながら、出力したファイル内に、日本語を書き込んでも、問題有りません。

    さらに、PATHをすべて英文字にすると全く問題有りません。

    C:\outpath\outinfo.html .... OK

    C:\出力パス\出力情報.html .... BAD!

     

    2006年2月10日 0:49

すべての返信

  • とりあえずどんなソースか出してくださらないとわからないです。(^^;;
    2006年2月10日 1:10
  • 返信ありがとうございます。ソースは、ちょっと出せないのですが、プログラムその物は、VC6で、問題なく動作するものです。だから、恐らく、Experss C++ 2005の問題であろうと思ったのでですが。そう言う例は、無いのでしょうか。
    2006年2月10日 2:02
  • 日本語パスといっている文字列の中で、Shift_JISの2バイト目のコードが0x20のもの

    (例えばば'ソ','能','表'等)があれば、OSの関係でできない場合とかあるかもしれません。

    (VCで\と解釈することはなさそうなんだけど、、、)

     

    単純に

    マルチバイト文字でなく、ワイド文字としてみてはどうでしょうか?

    # まさかとは思うけど、2005のデフォルトの文字コードがUnicodeなので、

    # Win32APIを使うと、TCHARがWCHARになるので普通に""だとエラーになったから

    # CreateFile( ( LPCTSTR )"なんたら", ~ ) みたいな事はしていないですよね、、、

    2006年2月10日 2:44
  • 一番単純にファイル出力しているだけなんですが。
    その部分を、取りだしたものが以下のものです。

    int main(){
     ofstream myStream(fileName);
        outMyFile(myStrem);
    }

    void outMyFile(ofstream &os)
    {
     os << "<HTML>" << endl;
      :
      :
      :
      :
      :
    }


    デバッガで、fileName が正しく日本語のパスになっている事を確認しています。
    ですが、文字化けしたファイル名になります。

    一度返信しましたが、タグを含んでいたので、めちゃめちゃ表示がおかしくなったので、書き直しました。

    2006年2月10日 4:25
  • とっちゃんです。

    蒼の洞窟 さんも指摘していますが、UNICODE オプションとかが影響している可能性が高そうな気がします。

    ためしに、最初に提示されたパスと、サンプルソースを元に VC2005 Express で
    動くものを作ってみました(コンソールプロジェクトのデフォルト設定のまま)が
    きちんと意図したパスでファイルが作られましたよ。

    もちろん、事前にフォルダは用意していますけど(^^;

    ソースは以下のものです(デフォルト設定のままコードを追加しただけ)。



    #include <fstream>
    using namespace std;
    void outMyFile( ostream& os )
    {
        os << _T("<HTML>") << endl;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        const TCHAR* szPath = _T("c:\\出力パス\\出力情報.html");
        ofstream myStream( szPath );
        outMyFile( myStream );
        return 0;
    }

     

    このコードで、実際に試してみましたけど(中身は、まぁ見ての通りですが)、きちんとファイルとして出力されていました。

    //追記
    でも、中身が文字化けしてました...orz
    004166FC って...

    2006年2月10日 14:31
  • >  でも、中身が文字化けしてました...orz
    > 004166FC って...

    std::ofstream はwchar_t型配列の文字列に対応していないからでしょう。
    (std::basic_ofstream<char, std::char_traits<char>>ですから)

    そもそも、TCHAR を前提にするのならば、


    #include <string>
    #include <fstream>
    #include <locale>
    #include <tchar.h> 
    
    namespace win32
    {
        typedef std::basic_string< TCHAR > string;
        typedef std::basic_ofstream< TCHAR > ofstream;
    }
    
    int _tmain( int argc, TCHAR* argv[] )
    {
        win32::string path = _T( "c:\\出力パス\\出力情報.html" );
        win32::ofstream fout( path.c_str() );
        fout.imbue( std::locale( "japanese" ) );
        if ( fout.is_open() )
        {
            fout << _T( "<HTML>" ) << std::endl
                 << path << std::endl
                 << _T( "</HTML>" );
            fout.close();
        }
        return 0;
    } 

    みたいにします。

    追記:カナーリ編集しました。夜中で参照している方が少なければいいのですが、、、

    2006年2月10日 15:52
  • とっちゃん@ごみまきモード(^^; です

    >std::ofstream はwchar_t型配列の文字列に対応していないからでしょう。

    あぅぅ~。すっかり忘れてました...orz

    そういえば、<char> でしたね。。。使ってないのバレバレだわ(^^;

    しかもきっちりとロケール設定や、エラーチェックまで入ってるし(おいらも見習わないと...)

     

    2006年2月13日 2:58
  • 返信頂きありがとうございます。しかもサンプルまで。これを参考に色々試してみたいと思います。

     

    2006年2月14日 0:17
  • まったく同じ状況になったわけではありませんが
    プロジェクトのプロパティの全般の内容で文字セットが
    「UNICODE文字セットを使用する」になっているとXXXA関数でなくXXXW関数になるので文字化けしますので
    「マルチバイト文字セットを使用する」に設定すると直ると思います。

    2006年2月20日 0:41

  •     locale::global(locale("japanese"));


    をmainの最初に記述して、回避できませんかね。

    この現象は、コンパイルの文字コードがマルチバイトのときに発生します。

    ちょっと奥までデバッグしてみたのですが、
    stlのコードがVC6とVC2005で変わってまして、
    ファイル名を一旦UNICODEに変換して、ワイド文字のファイルオープンを呼び出してました。
    このとき、UNICODEに変換するロジックが、グローバルロケールを参照しており、
    setlocaleなしでは"C"ロケールであると認識し、文字化けが発生していました。

    VC6とVC2005の非互換と思われます。

    2006年5月2日 4:30