我在使函数使用Calloc处理矩阵时遇到问题 [英] I have problems making a function to handle a matrix using calloc

查看:43
本文介绍了我在使函数使用Calloc处理矩阵时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用一个函数从文本文档中动态构造C语言的矩阵.在使用calloc制作矩阵时以及在将值赋给矩阵元素时遇到了问题,但我什么也找不到.我可以处理向量.

I want to dynamicly construct a matrix in C from a text document using a function. I ran into problems when making the matrix using calloc and probably when giving the values to the matrice elements, and I couldn't find anything. I can handle a vector.

此处的代码:

#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

这也是我用来收集信息的代码:

Also here is the code that I used to gather information:

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");
...
}

推荐答案

以下项目符号列出了函数中错误的项目.

The following bullet-list the items wrong in your function.

  • 您错误地将 feof()用作 while 循环的中断条件.请参阅此问题以获取更多信息.

  • You're incorrectly using feof() as the break condition of your while loop. See this question for more information.

您忽略 fscanf()的返回结果代码> ,因此无法保证参数解析成功与否.请参阅 fscanf() 的文档.

You ignore the return result of fscanf() and with that thereby have no assurance at all the parameter parsing succeeded or not. See the documentation of fscanf().

您的代码不适合文件内容的模型.根据您的代码,该文件应将 ir suly csom el 设置为值 0 0 7 8 .然后,您为恰好两个指向int的指针分配空间,将结果保存在 ellista 中,然后继续索引到 * ellista 中,直到 el 项,显然不是 2 .不清楚还是不希望在完成时想要2xN矩阵还是Nx2矩阵,并且编写的代码正确地 都不是.

Your code does not fit the model of the file content. The file, according to your code, should set ir, suly, csom, and el to values 0, 0, 7, and 8 respectively. You then allocate space for exactly two pointers-to-int, saving the result in ellista, then proceed to index into *ellista up to el items, which is clearly not 2. It is neither clear nor evident that you want a 2xN matrix or an Nx2 matrix when this is finished, and the code as-written does neither correctly.

有风格,但有帮助:您应该在函数的成功而不是在初始输入或解析时设置输出参数.例如:根据功能的成功,您的 ellista by-address参数应设置为 last 操作,而不是第一个操作.声明一个本地 int ** local; temp var,运行填充该算法的算法,并在成功成功后设置输出参数.

Stylistic, but helpful: You should be setting your out-parameters on success of your function, not on initial entrance or parse. Eg: Your ellista by-address parameter should be set as the last operation, not the first, based on the success of the function. Declare a local int** local; temp var, run your algorithm populating that, and upon success set the out-parameter.

所有这些都说明了,我认为,您需要一个2xN的矩阵,如果是这样,下面的代码将做到这一点.请注意,这 not 不会检查malloc和calloc调用的结果,我将留给您.成功时此函数将返回零( 0 ),失败时将返回非零:

All of that said, I think you want a 2xN matrix, and if so, the code below will do that. Note this does not check the results of the malloc and calloc calls, which i leave to you. This function will return zero (0) on success, non-zero on failure :

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;
}

这篇关于我在使函数使用Calloc处理矩阵时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆