1

昨日、コードの特定の部分に関する問題を投稿しました。目的は、基本的に、データ値を .dat ファイルから配列にスキャンし、値を出力しながら、ファイル内の値の数をカウントすることでした。

非常に単純に聞こえますが、私のプログラムは特定の数の値しか出力していないように見えました。より具体的には、300000 を超える値を含むデータ ファイルの場合、最後の 20000 のみを出力し、他には何も出力しません。

だから私はそれを残して、残りのコードを完成させました。そして今、私がソートしなければならない最後の部分です. いくつかの変更を加えて、出力 .dat ファイルを実際に印刷してみました。ちなみにコードは以下。

最初は、おそらく配列のメモリ割り当てに関連するものだと思っていたので(コード全体をまとめるとセグメンテーションエラーが発生しましたか?)、代わりに値の数をカウントする外部関数を作成しました(動作します)。

私の唯一の問題は、まだ 20000 の値のみを出力することを選択し、残りは 0 であることです。おそらくタイプと関係があると思っていましたが、科学表記法ではすべて7 dpsが含まれています。いくつかの値のサンプルを次に示します。

   8.4730000e+01   1.0024256e+01
   8.4740000e+01   8.2065599e+00
   8.4750000e+01   8.3354644e+00
   8.4760000e+01   8.3379525e+00
   8.4770000e+01   9.8741315e+00
   8.4780000e+01   9.0966478e+00
   8.4790000e+01   9.4760274e+00
   8.4800000e+01   7.1199807e+00
   8.4810000e+01   7.1990172e+00

私がどこで間違っているのか誰にもわかりますか?長い質問で申し訳ありません。最後の日かそこらの間、私を悩ませていました。何を変更しても、何も役に立たないようです。どんな種類の入力でも大歓迎です。

#include <stdio.h>
#include <stdlib.h>

int count(int);

const char df[]="data_file.dat";
const char of[]="output_file.dat";

int main(int argc, char *argv[])
{
    FILE *input, *output;
    int   i, N;
    float *array;

    N = count(i);

    input = fopen(df, "r");
    output = fopen(of, "w");

    array = (float*)malloc(N*sizeof(float));

    if((input != (FILE*) NULL) && (output != (FILE*) NULL))
    {
        for(i = 0; i < N; i++)
        {
            fscanf(input, "%e", &array[i]);
            fprintf(output, "%d %e\n", i, array[i]);
        }

        fclose(input);
        fclose(output);
    }
    else
        printf("Input file could not be opened\n");

    return(0);
}

int count(int i)
{
    FILE *input;
    input = fopen(df, "r");

    int N = 0;

    while (1)
    {
        i = fgetc(input);
        if (i == EOF)
            break;
        ++N;
    }

    fclose(input);

    return(N);
}
4

2 に答える 2

2

最大の問題は、count()float 値をカウントしないことです。ファイル内の文字数をカウントします。fscanf()次に、ファイル内の値よりも多くの回数ループして呼び出しを試みます。最初fscanf()は、float 値を見つけてスキャンします。しかし、ループがファイルの終わりに達するとfscanf()、EOF ステータスが返されます。EOFを返すときにfscanf()float値を設定する可能性があるようです。0.0

float 値を事前にカウントしないように書き直すことをお勧めします。fscanf()EOF の結果が返されるまで繰り返し呼び出すだけのループを作成し、ループから抜け出してファイルを閉じます。

PS のような関数を作成する場合count()は、ファイル名をハードコーディングするのではなく、引数として渡す必要があります。のバージョンはcount()整数の引数を取りますが、値を無視するだけです。代わりに、 内で一時変数を宣言するだけですcount()

編集:さて、これはこの問題を解決するための完全な作業プログラムです。

#include <stdio.h>

int
main(int argc, char **argv)
{
    FILE *in_file, *out_file;
    unsigned int i;

    if (argc != 3)
    {
        fprintf(stderr, "Usage: this_program_name <input_file> <output_file>\n");
        return 1; // error exit with status 1
    }

    in_file = fopen(argv[1], "r");
    if (!in_file)
    {
        fprintf(stderr, "unable to open input file '%s'\n", argv[1]);
        return 1; // error exit with status 1
    }

    out_file = fopen(argv[2], "w");
    if (!out_file)
    {
        fprintf(stderr, "unable to open output file '%s'\n", argv[2]);
        return 1; // error exit with status 1
    }


    for (i = 0; ; ++i)
    {
        int result;
        float x;

        result = fscanf(in_file, "%e", &x);
        if (1 != result)
            break;

        fprintf(out_file, "%d %e\n", i, x);
    }

    return 0; // successful exit
}

このバージョンでは大きな配列を割り当てる必要がないことに注意してください。一時的な float 変数が 1 つだけ必要です。おそらく、プログラムはすべての float 値を格納する必要があります。その場合、float 値をカウントするためcount()に使用して、上記のループと同様のループを使用する関数を作成します。fscanf()

fopen()また、このプログラムはとを呼び出した後にエラーをチェックすることに注意してくださいfscanf()

于 2013-01-18T20:06:36.063 に答える
0

N はファイル内の値の数ではなく、ファイル内の文字数であるため、必要以上に多くの浮動小数点数をメモリ (N) に割り当てています。また、ファイルに 300000 個の値があることをどのように判断しましたか?

于 2013-01-18T20:13:57.783 に答える