本ページは公開が終了した情報の複製であり、掲載時点での情報です。本ページに記載されている内容について各所に問い合わせることはご遠慮下さい。
サポート技術情報

[MSVC]テキストモードでのfread関数でのトラブル

文書番号: 402067

最終更新日: 1999/08/19


この資料は以下の製品について記述したものです。


この記事は、以前は次の ID で公開されていました: JP402067

概要

この資料は、C 6.0、C/C++ 7.0A、Visual C++ 1.0 および Visual C++ 1.5 の
MS-DOS 用ランタイムライブラリ関数 fread の障害について説明したものです。

詳細

前述の製品に添付のランタイムライブラリ関数 fread でファイルを
fopen でテキストモードでオープンしている場合に限り。
読み込むファイルサイズの演算を誤り、ファイルサイズより余計に読み込んで
しまいます。

再現プログラム

  <TEST.TXT>
  == TEST DATA START==
   1 2 3 4 5 6 7 8 9 0
   A B C D E F G H I J
   a b c d e f g h i j
  == TEST DATA  END ==
  <foo.c>
  #include <stdio.h>
  #include <malloc.h>
  void main(void)
  {
    FILE         *fp;
    unsigned char *buff;
    buff = (unsigned char *)malloc (1000);
    fp = fopen("TEST.TXT","rt");
    fread(buff, 1000, 1, fp);
    printf ("%s", buff);
    fclose (fp);
    free (buff);
  }

原因

テキストモードでの読み込みの場合、キャラクターコード 0x0A 0x0D を 0x0A へ
変換する作業をします。そのため読み込み後のデータサイズは、変換した分 小さ
くなりますが C 6.0 以降に添付されている fread 関数では、この変換によるサ
イズの変更に対する処理が正しく行われていません。
そのため、C6.0 以降では余分にデータを読み込んでしまうという現象が発生します。 例えば、ファイルサイズが 1,000 バイトで、変換後のサイズが 800 バイトになる
データの場合。C6.0 以降の fread 関数では、800 バイトまで正しく読み込んだあと、 200 バイト余計に読み込んでしまいます。

対処方法

残念ながら、モジュールの修正による対応は現状では行えませんので、
誠に恐れ入りますが、以下の方法で対応されるようお願い申し上げます。
fread 関数の第2パラメータ (Item サイズ) に1を指定し、
第3パラメータ (Item Count) に読み込みバッファの容量をバイト単位で指定し、
fread 関数の戻り値を変数に受け取ります。
これで 第1パラメータで指定したバッファに読み込まれ、戻り値に変換後のデータ
サイズ(バイト単位)が代入されます。
バッファに読み込まれたデータは、fread の戻り値バイトまでが有効なデータになって いますので、以下の様に fread の戻り値バイト目に NULL を挿入すれば。それ以降の 処理をしやすくなります。

対応プログラム例

  <foo.c>
  #include <stdio.h>
  #include <malloc.h>
  void main(void)
  {
    FILE        *fp;
    unsigned char *buff;
    size_t sz;  // 変換後のデータサイズ保存用変数
    buff = (unsigned char *)malloc (1000);
    fp = fopen("TEST.TXT","rt");
    sz = fread(buff, 1, 1000, fp);  // データ読み込み/変換後のデータサイズ取得
    buff[sz] = 0;                   // 有効なデータの最後に NULL を挿入
    printf ("%s", buff);
    fclose (fp);
    free (buff);
  }
なお、この現象は Visual C++ 2.0 に添付の NT 用ランタイム関数では発生しません。

Keywords: C6 C7 KBBUG VC10 VC15 KB402067
Technology: kbAudDeveloper kbCCompPDS600DOS kbCCompSearch kbPWBSearch kbVCsearch kbZNotKeyword3 kbZNotKeyword8

inserted by FC2 system