ファイルから格納した配列のサイズを知りたい

解決


トシ  2007-01-27 03:18:35  No: 64303

例えば、
      fp = fopen(test.txt, "r");
でtest.txtファイルをオープンし、
      for(k = 0; k < 5000; k++)
      {
  fscanf(fp, "%lf\n", &test[k][0], &test[k][1]);
      }
と、test[5000][0]で定義された配列の中に数字を格納していきます。

このときtest.txtに入っているデータの行数はわからないとします。
このままですと、プログラム上でtest[5000][0]のどこまでデータが入っていったのかがわかりません。

こういった場合に、配列の何行目までデータが入ったか、つまりもとのテキストデータに何行のデータが入っていたかを知りたい場合はどのようにすればよいでしょうか?
最初はMATLABのように、lengthといったような関数で配列のサイズを取得できるのかなとも考えたのですが、Cでは先に配列のサイズを宣言してしまうため、こういった作業をするのにどうすればいいかわからなくなってしまいました。

どなたか教えていただけないでしょうか?
よろしくお願いします。


通りすがり  2007-01-27 03:40:33  No: 64304

fscanfの戻り値チェックすれば解決
なぜマニュアル見ないの?

>fscanf(fp, "%lf\n", &test[k][0], &test[k][1]);
書式制御文字列にひとつしかないのに&test[k][1]って?


トシ  2007-01-27 04:00:16  No: 64305

>通りすがり様
コメントありがとうございます。
マニュアルを読んでもわからなかったので、質問をさせていただきました・・・
力がなくてすいません
あと、指摘していただいたのは記述ミスです

早速言われたとおり、戻り値のチェックをしてみたのですが、
        for(k = 0; k < 5000; k++)
      {
              N = fscanf(fp, "%lf\n", &test[k][0]);
      }
としても、N=-1と返ってきてしまい、サイズを読み込めませんでした・・・
どこがまずいのでしょうか?

よろしくお願いします。


ぴろぴろ  2007-01-27 06:56:04  No: 64306

自分で読み込んだ数をカウントすればいいだけの話。

      int length = 0;
      
      fp = fopen(test.txt, "r");
      for(k = 0; k < length; k++)
      {
            length += fscanf(fp, "%lf\n", &test[k][0]);
            length++;
      }

でも、ファイルの終わりを検知せずにループを続けるのはいいのか?


ぴろぴろ  2007-01-27 06:56:59  No: 64307

↑length++を消し忘れた。

      int length = 0;
      
      fp = fopen(test.txt, "r");
      for(k = 0; k < length; k++)
      {
            length += fscanf(fp, "%lf\n", &test[k][0]);
      }


超初心者  2007-01-27 08:04:56  No: 64308

以下は動作確認していないので間違えているかも知れません。

fscanfで読み取れなかったらbreakでforを終了すればいいだけでしょ。

for(k = 0; k < 5000; k++)
{
  int n = fscanf(fp, "%lf\n", &test[k][0]);
  if(n<1) break;
}

これだと数値じゃないからfscanfが失敗したのか
ファイルの終わりか
それ以外のエラーかわからないけどね。


通りすがり  2007-01-27 10:41:54  No: 64309

5000固定でいいのかとか突っ込まないとするなら
EOFが帰ったときbreakしてkの値を見ればいい

fscanf
http://msdn2.microsoft.com/ja-jp/library/cb5kac8b(VS.80).aspx
戻り値
これらの関数は、正常に変換および代入されたフィールドの数を返します。読み込まれただけで代入されなかったフィールドは戻り値には含まれません。戻り値が 0 の場合は、代入されたフィールドがなかったことを示します。エラーが発生した場合や、最初の変換の前にファイル ストリームの終端を検出した場合、fscanf および fwscanf は EOF を返します。


通りすがり  2007-01-27 10:47:21  No: 64310

>ぴろぴろ氏
終端到達するとEOF(-1)が帰って
そのコードだと引かれまくってしまうような…


トシ  2007-01-27 19:00:49  No: 64311

みなさんコメントありがとうございました。
無事解決できました。

while(!feof(fp))でファイルの終端を読み取り、そのループ内で変数を1ずつカウントすることで解決できました。
また、なにかありましたらよろしくお願いします。


ぴろぴろ  2007-01-31 10:24:10  No: 64312

通りすがり氏
>終端到達するとEOF(-1)が帰って
確かにそうなりますね。
終端到達時の戻り値が-1というのが抜けてました。


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

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






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