1

関数を使用して、テキスト ドキュメントから C でマトリックスを動的に構築したいと考えています。calloc を使用して行列を作成するとき、およびおそらく行列要素に値を与えるときに問題が発生し、何も見つかりませんでした。ベクトルを扱うことができます。

ここにコード:

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

void beolvas_ellista(int *, int *, int *, int *, int ***, char *);

int main()
{
    int ir, suly, csom, el, i, **ellista;

    //The following commented code works
    /*FILE * f;
    f=fopen("be.txt","r");

    fscanf(f,"%d",&ir);
    fscanf(f,"%d",&suly);
    fscanf(f,"%d",&csom);
    fscanf(f,"%d",&el);

    ellista=(int **)calloc(2,sizeof(int *));
    for(i=0;i<el;++i)
    {
        ellista[i]=(int *)calloc(el,sizeof(int));
    }
    i=0;
    while(!feof(f))
    {
        fscanf(f,"%d",&ellista[0][i]);
        fscanf(f,"%d",&ellista[1][i]);
        ++i;
    }

    for(i=0;i<el;++i)
        printf("%d %d\n",ellista[0][i],ellista[1][i]);

    fclose(f);*/

    beolvas_ellista(&ir, &suly, &csom, &el, &ellista, "be.txt");

    for(i=0;i<el;++i)
        printf("%d %d\n",ellista[0][i],ellista[1][i]);

    return 0;
}

void beolvas_ellista(int *ir, int *suly, int *csom, int *el, int ***ellista, char *allomany)
{
    int i;
    FILE * f;
    f=fopen(allomany,"r");

    fscanf(f,"%d",ir);
    fscanf(f,"%d",suly);
    fscanf(f,"%d",csom);
    fscanf(f,"%d",el);

    *ellista=(int **)calloc(2,sizeof(int *));
    for(i=0;i<*el;++i)
    {
        *ellista[i]=(int *)calloc(*el,sizeof(int));
    }

    i=0;
    while(!feof(f))
    {
        fscanf(f,"%d",ellista[0][i]);
        fscanf(f,"%d",ellista[1][i]);
        ++i;
    }

    fclose(f);
}

テキストファイルは次のとおりです。

be.txt

0 0
7 8
1 2
1 3
2 3
3 4
4 5
4 6
5 7
6 7

また、情報を収集するために使用したコードは次のとおりです。

void beolvas(int*pn, int**pa, char*allomany)
{
int i;FILE*f;
f=fopen(allomany,"r");
fscanf(f,"%d",pn);
*pa=(int*)malloc((*pn)*sizeof(int));
for(i=0; i<*pn; i++)
fscanf(f,"%d",(*pa)+i);
fclose(f);
}
main()
{
int n, *a;
beolvas(&n, &a, "be.txt");
...
}
4

2 に答える 2

0

次の箇条書きは、関数で間違っている項目をリストしています。

  • ループfeof()のブレーク条件として間違って使用しています。詳細については、この質問を参照してください。while

  • andの戻り結果を無視するfscanf()と、パラメーターの解析が成功したかどうかはまったく保証されません。のドキュメントを参照してくださいfscanf()

  • コードがファイル コンテンツのモデルに適合していません。コードによると、ファイルは、、、、およびをそれぞれ値、、、irおよびにsuly設定する必要があります。次に、正確に2 つの int へのポインターにスペースを割り当て、結果を に保存してから、アイテムまでのインデックスに進みますが、これは明らかに ではありません。これが終了したときに 2xN 行列または Nx2 行列が必要であることは明確でも明白でもなく、記述されたコードはどちらも正しくありません。csomel0078ellista*ellistael 2

  • 文体的ですが、役立つ:最初の入り口や解析ではなく、関数の成功時に out-parameters を設定する必要があります。例: ellistaby-address パラメーターは、関数の成功に基づいて、最初ではなく最後の操作として設定する必要があります。ローカル一時変数を宣言し、int** local;それを入力してアルゴリズムを実行し、成功したら out-parameter を設定します。

そうは言っても、2xN 行列が必要だと思います。もしそうなら、以下のコードがそれを行います。これはmalloc および calloc 呼び出しの結果をチェックしないことに注意してください。この関数は0、成功するとゼロ ( ) を返し、失敗するとゼロ以外を返します。

int beolvas_ellista(int *ir, int *suly, int *csom, int *el, int ***ellista, const char *allomany)
{
    FILE * f = fopen(allomany,"r");
    int ** local =  NULL;
    int i, res = -1;

    if (f == NULL)
        return res;

    if (fscanf(f,"%d",ir) == 1 &&
        fscanf(f, "%d",suly) == 1 &&
        fscanf(f,"%d",csom) == 1 &&
        fscanf(f,"%d",el) == 1)
    {
        // allocate two pointers, then in those two pointers, allocate
        //  space for *el integers.
        local = malloc(2 * sizeof(*local));
        local[0] = calloc(*el, sizeof(*(local[0])));
        local[1] = calloc(*el, sizeof(*(local[0])));

        for (i=0; i<*el; ++i)
        {
            if (fscanf(f, "%d", local[0]+i) != 1 ||
                fscanf(f, "%d", local[1]+i) != 1)
                break;
        }

        // only if i == *el did we finish the above
        if (i == *el)
        {
            *ellista = local;
            res = 0;
        }
        else
        {   // failed to read file content. free up memory
            // and return error state.
            free(local[0]);
            free(local[1]);
            free(local);
        }
    }
    fclose(f);
    return res;
}
于 2013-10-28T19:48:31.860 に答える