質問者
日本語PATH文字化け

質問
-
初めまして、よろしくお願いします。
Express C++ 2005で、コンソールアプリを作りました。
ファイルを出力する処理を行っているのですが、日本語のPATHだと、出力されないか
文字化けしたファイル名になってしまいます。Win32 SDKが、Englishになっているから
でしょうか。でも、コンソールに対しての日本語文字列出力は問題有りませんし、
当然ながら、出力したファイル内に、日本語を書き込んでも、問題有りません。
さらに、PATHをすべて英文字にすると全く問題有りません。
C:\outpath\outinfo.html .... OK
C:\出力パス\出力情報.html .... BAD!
すべての返信
-
日本語パスといっている文字列の中で、Shift_JISの2バイト目のコードが0x20のもの
(例えばば'ソ','能','表'等)があれば、OSの関係でできない場合とかあるかもしれません。
(VCで\と解釈することはなさそうなんだけど、、、)
単純に
マルチバイト文字でなく、ワイド文字としてみてはどうでしょうか?
# まさかとは思うけど、2005のデフォルトの文字コードがUnicodeなので、
# Win32APIを使うと、TCHARがWCHARになるので普通に""だとエラーになったから
# CreateFile( ( LPCTSTR )"なんたら", ~ ) みたいな事はしていないですよね、、、
-
一番単純にファイル出力しているだけなんですが。
その部分を、取りだしたものが以下のものです。int main(){
ofstream myStream(fileName);
outMyFile(myStrem);
}void outMyFile(ofstream &os)
{
os << "<HTML>" << endl;
:
:
:
:
:
}
デバッガで、fileName が正しく日本語のパスになっている事を確認しています。
ですが、文字化けしたファイル名になります。一度返信しましたが、タグを含んでいたので、めちゃめちゃ表示がおかしくなったので、書き直しました。
-
とっちゃんです。
蒼の洞窟 さんも指摘していますが、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 って... -
> でも、中身が文字化けしてました...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; }
みたいにします。追記:カナーリ編集しました。夜中で参照している方が少なければいいのですが、、、
-
locale::global(locale("japanese"));
をmainの最初に記述して、回避できませんかね。
この現象は、コンパイルの文字コードがマルチバイトのときに発生します。
ちょっと奥までデバッグしてみたのですが、
stlのコードがVC6とVC2005で変わってまして、
ファイル名を一旦UNICODEに変換して、ワイド文字のファイルオープンを呼び出してました。
このとき、UNICODEに変換するロジックが、グローバルロケールを参照しており、
setlocaleなしでは"C"ロケールであると認識し、文字化けが発生していました。
VC6とVC2005の非互換と思われます。