トップ回答者
basic_ifstreamの型

質問
-
お世話になります。
現在basic_ifstreamではまってしまっています。
以下のような2種類のコードを書いてみました。
日本語が混在したフォルダのファイル読み込み
C:\Temp\てすとふぉるだ\test.txt
内容:
163638 1737383 あいうえお
193838 893939 かきくけこ
983839 1838383 さしすせそ
のような感じ。ディリミタはタブ。改行はLF。
というファイル(中身はEUC)を読み込む際のコード
コンパイルはUNICODEでコンパイルしています。
// basic_ifstreamの型をTCHARにして読み込み
bool func1(LPCTSTR lpPath)
{
std::basic_ifstream<TCHAR> aFile(lpPath);
if (! aFile.is_open()) return false;aFile.imbue(std::locale("japanese"));
TCHAR buff[BUFSIZ];while (aFile.getline(buff, BUFSIZ-1))
{....
}
return true;
}bool func2(LPCTSTR lpPath)
{
std::ifstream aFile(CT2A(lpPath)); // charに修正
if (! aFile.is_open()) return false;char buff[BUFSIZ];
while (aFile.getline(buff, BUFSIZ-1))
{
....
}return true;
}func1の方法ですと、getlineで数行読み込んだだけで、ファイルの終端まで到達する前にループを抜けてしまいます。
func2の方法ですと、パスの日本語の部分が化けてしまってオープンできない症状が出てしまいます。
どのようにすると正常に読み込みできる状態となりますでしょうか?
よろしくお願いいたします。
回答
-
>> だったらTCHARで取り込んじゃダメでしょ(UNICODEモードだとガタガタになるっしょ)。
>> char決め打ちのifstreamからgetlineし、読み込んだchar[]を変換せんと。>
> はい、それで、func2のような手法で実行してみたのですが、以下のような問題が発生している次第です。
> ・パスの日本語部分がstd::ifstreamのopenの中で文字化けし、正常なパスとされないため、失敗してしまう。
てことはCT2Aがちゃんと変換してくれていないってことがはっきりしてますよね?
- このときlpPathはUNICODEすなわち TCHAR = wchar_t ですか?
- CT2Aの使い方、ホントにこれで正しいのですか? (僕は知りません、疑ってるんです)
すべての返信
-
επιστημηさん、早速のご返信ありがとうございます。
- 食わすファイルが日本語を含まないなら、ちゃんと読みますか?
日本語を含まない場合は読めています。
- 食わすファイルの日本語がShift_JISなら、ちゃんと読みますか?
Shift_JISにした場合は、オープンはできますが、getlineでは1行も取ってくることができず、ループをそのまま素通りしてしまいます。
- おそらくEUCを(コード変換を伴って)読ますのは困難ですよ。
一旦読んでからShift_JISなりUnicodeに変換してあげないと。一応、getlineで取得後、EUCからShift_JISに変換するようなことは行っています。
ちなみにですが、ファイルのパスに日本語を含まない場合は、func2の手法でも普通に読むことができています。しかし、この場合、func1の手法ですと、ファイル終端まで行かずにループを抜けてしまいます。
-
επιστημη さん、ご返信ありがとうございます。
> だったらTCHARで取り込んじゃダメでしょ(UNICODEモードだとガタガタになるっしょ)。
> char決め打ちのifstreamからgetlineし、読み込んだchar[]を変換せんと。はい、それで、func2のような手法で実行してみたのですが、以下のような問題が発生している次第です。
・パスの日本語部分がstd::ifstreamのopenの中で文字化けし、正常なパスとされないため、失敗してしまう。
⇒_Fiopen()の中のmbstowcs_s()でパスの日本語が化けてしまいます。
恐れ入りますが、問題点について更にご指摘いただければ幸いです。
よろしくお願いいたします。
-
>> だったらTCHARで取り込んじゃダメでしょ(UNICODEモードだとガタガタになるっしょ)。
>> char決め打ちのifstreamからgetlineし、読み込んだchar[]を変換せんと。>
> はい、それで、func2のような手法で実行してみたのですが、以下のような問題が発生している次第です。
> ・パスの日本語部分がstd::ifstreamのopenの中で文字化けし、正常なパスとされないため、失敗してしまう。
てことはCT2Aがちゃんと変換してくれていないってことがはっきりしてますよね?
- このときlpPathはUNICODEすなわち TCHAR = wchar_t ですか?
- CT2Aの使い方、ホントにこれで正しいのですか? (僕は知りません、疑ってるんです) -
-
こんにちは、フォーラム オペレータ大久保です。
επιστημη さん、いつもご利用ありがとうございます。
さしつかえなければ、επιστημη さんならどう対応するか、一例でいいので教えていただけると皆さんの参考になると思うんですが…
細かいシチュエーションがいろいろ考えられると思うので難しいとは思いますが、επιστημη さんがよく使うパターンがあればご紹介いただけませんか?
kfsh さん、勝手とは思いましたが、επιστημη さんの回答が解決の糸口になったようなので、回答済みのチェックをつけさせていただきました。
もし不適切でしたらチェックを解除することもできますのでご確認ください。
それでは。
-
> さしつかえなければ、επιστημη さんならどう対応するか、一例でいいので教えていただけると
> 皆さんの参考になると思うんですが…
> 細かいシチュエーションがいろいろ考えられると思うので難しいとは思いますが、
> επιστημη さんがよく使うパターンがあればご紹介いただけませんか?
えー、そいじゃ...
1. shift_jis/UTF16/UTF8 のみ対応、VC++9, C++/CLI のとき
→ marshalling library
2. いろんな文字コード、C++/CLI のとき
→ .NET Framework の Encoding族
3. shift_jis/UTF16 のみ対応、nativeのとき
→ 標準 wcstombs/mbstowcsとlocaleのコンボ
4. いろんな文字コード、nativeのとき
→ IBM製ICU
などなど、そんなのを使ってます。