Unicodeテキストの1行読込み


matsu  2008-06-26 23:06:30  No: 68611

久しぶりに投稿します。

OS:WinXP Pro SP2
VS2005, VC++ MFC

プロジェクトのプロパティ[文字セット]  ⇒  マルチ バイト文字セットを使用する
Frameworkは使用しません。

タブ区切りのCSVを1行ずつ読込み分割して処理を行おうと思い、
ReadStringを使用しました。
簡単なプログラムと思っていたのですがCSVが「Unicode(UTF-16LE)、改行コードCRLF」
可変長で、ReadStringはSJIS前提という情報を見かけたのと1行分正確に読込まれないためfgetsに切替えました。

CSVの内容は以下のようなものです。

ああああ[TAB]いいいい[TAB]うううう[CRLF]
123ああ[TAB]4いい[TAB]5うう[CRLF]
abcd[TAB]efg[TAB]hijklm[CRLF]
    ・
    ・
(コード)
CString strResult = "";  // 1行格納用
CString strBPath = "xxxx.csv";
int nLen;

fopen_s(&fp, strBPath, "rb"); 

if(fp == NULL)
    return; 

while (1) {
    TCHAR buf[1000] = {0};
    if (fgets(buf, sizeof(buf), fp) == NULL)
        break;
    strResult = buf;
    nLen = strResult.GetLength();
}

(Unicode(UTF-16LE)、改行コードCRLF)CSV
1行目nLen:11
正解はBOM+で[30]でしょうか?

(同じ内容のSJIS、改行コードCRLF)CSV
1行目nLen:28

となります。

1.「Unicode(UTF-16LE)、改行コードCRLF」の1行を読込む方法を教えてください。
2.読込み(ワイド文字列として?)後、手動でBOMを削除し、wcstombs、WideCharToMultiByte等
    で変換する、でしょうか?
3.読込み後、手動で上位バイト、下位バイトの入替が必要ですか?
4.一発変換関数(たぶん、1行読込み成功後になるのでしょうが)とかご存知ありませんか?

以上、欲張りな質問になりましたが、よろしくお願いします。


matsu  2008-06-27 00:25:58  No: 68612

matsuです。

いつも投稿後に進展があります。すみません。
まず、先頭に
setlocale(LC_CTYPE, "jpn");
を追加しました。

> fopen_s(&fp, strBPath, "rb");
fopen_s(&fp, strBPath, "rb, ccs=UNICODE");
に変更。

> TCHAR buf[1000] = {0};
WCHAR buf[1000] = {0};
に変更。

な、な、なんと正常に読込みができました。
1.2.3.4.が一気に解決しました。
お騒がせしました。

ただ、先の質問とは異なる気になる点がありまして
1.読込む前にサイズを指定しますがCSVは可変長なので予測される最大値
    ということになるのでしょうか?
    サイズオーバー時はオーバー分は切捨てられますよね?
2.strResult = buf;は問題ないでしょうか?
    コンパイルも通りますし、メッセージボックスでも正常に表示されます。

よろしくお願いします。

あ、あと「BOMの処理は自前で」ですね?


matsu  2008-06-27 00:35:03  No: 68613

すみません、書き忘れました。

fgets  ⇒  fgetws

にしました。


そだ  2008-06-27 03:07:07  No: 68614

>可変長で、ReadStringはSJIS前提という情報を見かけたのと1行分正確に読込まれないためfgetsに切替えました。
LPTSTR を引数に持つぐらいなので対応してるのでは?

http://homepage3.nifty.com/aokura/tips/edit6.html
で、
>CStdioFile クラスのソースをみると、ReadString, WriteString 関数はそれぞれ C ランタイムの fgetws, fputws 関数を使って実装されており、現在のロケールの LC_CTYPE カテゴリに依存して動作することが分かります。

とあるのでReadStringでも動きそうな気がします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加