none
日本語のファイル出力について RRS feed

  • 質問

  • 毎度お世話になります。

    日本語のファイル出力(下記のコード参照)を行ないましたが、 "ああああ"の部分の書込は出来ませんでした。

    Q1) "ああああ"の部分の書込みを行なう方法はありますか

    お手数ですが、宜しくお願いします。

    CStdioFile    stdFile;
     CString       wstr, rstr;
     LPTSTR        rstrBuf = NULL;
     int           err = 0;

     if (!err){
      if (!stdFile.Open(_T("C:\\wk\\ファイルA.txt"),
       CFile::modeReadWrite | CFile::shareExclusive |
       CFile::modeCreate)) err = 1;
     }
     if (!err){
      wstr = _T("AAA\nBBB\nCCCああああ\n");  //"ああああ"の部分の書込は出来ず
      TRY{ stdFile.WriteString(wstr); }
      CATCH(CFileException, eP) { err = 1; }
      END_CATCH

     }
     
     if (!err){ // (3)シーク
      TRY{ stdFile.SeekToBegin(); }
      CATCH(CFileException, eP) {
       err = 1;
      }
      END_CATCH
     }
     
     if (!err){   // (4)読み込み(CString)
      if (stdFile.ReadString(rstr) == FALSE) err = 1;
      TRACE2("No1=%s err=%d\n", rstr,err);
     }
     if (!err){   // (4)読み込み(CString)
      if (stdFile.ReadString(rstr) == FALSE) err = 2;
      TRACE2("No2=%s err=%d\n", rstr,err);
     }

     if (!err){   // (5)読み込み(LPTSTR)
      rstrBuf = rstr.GetBuffer(32);
      if (stdFile.ReadString(rstrBuf, 32) == FALSE) err = 3;
      rstr.ReleaseBuffer();
      TRACE2("No3=%s err=%d\n", rstrBuf, err);
     }
     
     stdFile.Close(); // (6)クローズ(明示的)

    2015年11月27日 2:00

回答

  • CStdioFile でテキスト出力するときは、CFile::typeText を付ける必要があります。これは、内部的な実装の問題なので、回避できませんが、CFile のコンストラクタのフラグ説明にかろうじてもしかして?という程度の記述しかありません。いつの間にかリファレンスから消え去ってるみたいですね

    ただし!

    UNICODE版の場合は、これと併せて、CFile::typeUnicode を付け、なおかつ、ファイルの先頭に「自分で」BOM(Byte Order Mark)をいれてユニコードテキストとして扱う必要があります。

    読み取りだけの場合も同様です。

    また、UNICODE版では、ANSI版テキストは正しく読み取れず、逆にANSI版ではUNICODEテキストは正しく読み取れません。

    そういう場合は、CFileを使ってバイナリモードでオープンし、ファイルの内容に即して、自前でコード変換する必要があります。


    とっちゃん@わんくま同盟, Microsoft MVP for Visual C++ (Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク 星 睦美 2015年12月8日 2:26
    2015年11月27日 3:25

すべての返信

  • Open()のオプションを

    if (!stdFile.Open(_T("C:\\D\\ファイルA.txt"),
    CFile::modeReadWrite | CFile::shareExclusive |
    CFile::modeCreate|CFile::typeBinary)) err = 1;

    の様にバイナリモードでオープンすると書けるようですが、
    はっきり言って妙な仕様ですよね。
    CStdioFileクラスはかくのごとくやや問題のあるクラスなので、
    自分は使用禁止にしてます。CFileを使った方がはるかにましです。

    2015年11月27日 2:53
  • CStdioFile でテキスト出力するときは、CFile::typeText を付ける必要があります。これは、内部的な実装の問題なので、回避できませんが、CFile のコンストラクタのフラグ説明にかろうじてもしかして?という程度の記述しかありません。いつの間にかリファレンスから消え去ってるみたいですね

    ただし!

    UNICODE版の場合は、これと併せて、CFile::typeUnicode を付け、なおかつ、ファイルの先頭に「自分で」BOM(Byte Order Mark)をいれてユニコードテキストとして扱う必要があります。

    読み取りだけの場合も同様です。

    また、UNICODE版では、ANSI版テキストは正しく読み取れず、逆にANSI版ではUNICODEテキストは正しく読み取れません。

    そういう場合は、CFileを使ってバイナリモードでオープンし、ファイルの内容に即して、自前でコード変換する必要があります。


    とっちゃん@わんくま同盟, Microsoft MVP for Visual C++ (Oct 2005-) http://blogs.wankuma.com/tocchann/

    • 回答としてマーク 星 睦美 2015年12月8日 2:26
    2015年11月27日 3:25
  • みなさは、丁寧な説明有難うございました。

    2015年11月27日 8:53
  • もし とっちゃん さん提示の情報でもうまく出ないようなら、ロケールを設定するとよいです。



    #include <clocale>


    _tsetlocale(LC_ALL, _T(""));


    2015年11月30日 3:45