1

そこで、ファイルから行列を取得し、それを配列に入れ、その行列式を計算するコードをいくつか書きました。ただし、実行すると、配列に値が設定されていないように見え、プログラムは 0 行列を返すため、行列式 = 0 になります。ファイルプロセスからの読み取り全体を処理します。

このファイルは単なる .data ファイルであり、行列要素がスペースで区切られた列に格納されています。つまり、次のようになります。

1.7 1.2 0.5
0.0 -3.2 1.4
3.0 4.0 5.0

これが(私が思うに)コードの関連セクションですが、役立つ場合はすべてを投稿できます。

int main(int argc, char* argv[])
{
    FILE          *input;
    int           record, i, j;
    int           curr_col;
    const int     dim = DIMENSION;
    double        entries[dim][dim];
    double        tmp, determinant;
    const char    inp_fn[]="matrix.data";

    /* Open file */
    input = fopen(inp_fn, "r");

    /* Check the pointer to file are not NULL */
    if(input != (FILE*) NULL)
    {
        for(j=0; j<dim; j++, fopen(inp_fn, "r"))
        {
            record = 0; i = 0;
            /* Read in records one by one and check the return value of fscanf */
            while(fscanf(input,"%lf",&tmp) == 1)
            {
                curr_col = (record % dim);
                if(curr_col==j)
                {
                    /* Copy data points to the array */
                    entries[i][j] = (double)(tmp);
                    i++;
                }
                record++;
            }
            fclose(input);
        }
    }
    else
        printf("*** Could not open input or output file! ***\n");

    /* Calculates determinant */
    determinant = det(dim, entries);

    printf("\nA = \n");
    for(i=0; i<dim; i++)
    {
        for(j=0; j<dim; j++)
        {
            printf("%.1lf ", entries[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    printf("det(A) = %.3lf\n", determinant);

}

「入力または出力ファイルを開けませんでした!」というメッセージが表示されます。プログラムを実行すると、エラーと空の行列が表示されます...助けて!?

4

2 に答える 2

3

汚い修正

あなたのコードから、別の列を読むたびにファイルを開くというあなたの意図がわかります。それは非効率的で不格好です。次のように変更することで、機能させることができます(読み取り入力部分のみ、残りのコードについてはわかりません)。

for(j=0; j<dim; j++, fopen(inp_fn, "r"))

for(j=0; j<dim; j++, input = fopen(inp_fn, "r"))

現在のコードはファイルを開き、リソースを浪費しますが、ファイルは前の反復で閉じられているfcloseため、エラーが発生します。input

上記で提案したコードは、新しいFILE*fromfopenを to に割り当てinputます。

もちろん、最初に指摘したように、上記の方法は非常に非効率的です。


より良い方法

if ステートメント内のより良い方法if(input != (FILE*) NULL)( でループを削除しますj):

record = 0;
// Read the file at most (dim * dim) times to fill up the array
// The reading also stops when it cannot read any double number
while(fscanf(input,"%lf",&tmp) == 1 && record < dim * dim)
{
    // Use some math to calculate the cell to put the new entry
    entries[record / dim][record % dim] = tmp; // entries and tmp are double, no need for casting

    record++;
}

// Close the file after done reading
fclose(input);

fopen条件に入る前に一度だけ呼び出されif、すべてが一度に読み取られることに注意してください。

record == dim * dim提供されたデータが十分でない場合に備えて、読み取り後にチェックを追加して、それを確認することもできます。

于 2012-11-22T02:17:43.957 に答える
0

perror("fopen");printf の代わりに、オープニングが失敗したときにエラーを出力するために使用してみてください

また、for ループのたびにファイルを再度開いていることに注意してください。

変化する

for(j=0; j<dim; j++, fopen(inp_fn, "r"))

for(j=0; j<dim; j++)
于 2012-11-22T01:50:21.070 に答える