c - 我在使用 calloc 创建处理矩阵的函数时遇到问题

标签 c function parameter-passing calloc

我想使用函数从文本文档动态构建 C 矩阵。 我在使用 calloc 制作矩阵时遇到了问题,可能在给矩阵元素赋值时遇到了问题,但我找不到任何东西。我可以处理 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);
}

这是文本文件:

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

最佳答案

下面的项目符号列出了你的函数中错误的项目。

  • 您错误地使用 feof() 作为 while 循环的中断条件。 See this question了解更多信息。

  • 你忽略fscanf()的返回结果因此,根本无法保证参数解析成功与否。 See the documentation of fscanf() .

  • 您的代码不适合文件内容的模型。根据您的代码,该文件应将 irsulycsomel 设置为值 0078。然后,您恰好为 两个 指向 int 的指针分配空间,将结果保存在 ellista 中,然后继续索引到 *ellista 直到 el 项,显然不是 2。完成后,您想要 2xN 矩阵还是 Nx2 矩阵既不清楚也不明显,而且所写的代码均不正确

  • 文体,但有帮助:您应该在函数成功时设置输出参数,而不是在初始入口或解析时。例如:您的 ellista by-address 参数应该设置为last 操作,而不是第一个,基于函数的成功。声明一个本地 int** local; 临时变量,运行填充它的算法,并在成功时设置输出参数。

综上所述,我认为您需要一个 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;
}

关于c - 我在使用 calloc 创建处理矩阵的函数时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19642570/

相关文章:

c - 带有 UEXT 连接器和 PIC MCU 的 Olimex Zigbee 模块。为什么使用 PIC MCU 进行编程?

C和 Bison : pointers to struct in %union definition

c - 零填充字符串发出警告但仍然有效

javascript - 创建变量名函数

c - 如何从c中的库传递数组

c++ - 使用 strlen 时不为空终止符添加 +1 会导致在使用 send 时发送额外的垃圾字节

javascript - 获取下拉信息的按钮

php - WordPress 'If' 声明

带有参数作为函数参数的Javascript函数指针

c++ - 将参数传递给 C++ CORBA 方法实现