0

遇到了稍微复杂一点的代码部分的问题,我已经把它剥离了,但错误仍然存​​在。你能粗略地看看这个并指出我的错误吗?

//before this, nbnoeud is defined and graphe is a stream that reads from a .txt file

double* xtab = (double *) calloc(nbnoeud, sizeof(double));
double* ytab = (double *) calloc(nbnoeud, sizeof(double));
char** nomtab = (char **) calloc(nbnoeud, 100*sizeof(char));

double x, y; char nom[100]; int numero=0, scancheck;

int a;
for(a=0; a<nbnoeud; a++){
    scancheck = fscanf(graphe, "%d %lf %lf %[^\n]", &numero, &x, &y, nom);
    if(scancheck = 4) printf("Read item %d; \t Scancheck: %d; \t %s - (%lf, %lf). \n", numero, scancheck, nom, x, y);
    xtab[a] = x; 
    ytab[a] = y;
    nomtab[a] = nom; I imagine it's something to do with compatibility of this but to my eyes it all checks out
    /*int b; //this section just illustrates that only the previously accessed elements are being overwritten. See code2.png
    for(b=0; b<=nbnoeud; b++){
        printf("%s \n", nomtab[b]);
    }*/
}

for(a=0; a<nbnoeud; a++){
    printf("Read item %d; \t \t \t %s - (%lf, %lf). \n", a, nomtab[a], xtab[a], ytab[a]);
}

exit(1);

当我nomtab[0]通过[7]( nbnoeud = 8,在这种情况下) 进行打印时,问题就出现了,因为所有值 ( nomtab[0]nomtab[1]等) 都等于写入的最终值。奇怪的是,经过检查,只有已经访问过的元素nomtab被覆盖。例如,在第一个循环之后,nomtab[0]= Aaa其余的等于null;在第二个循环之后,nomtab[0]&nomtab[1] = Baa和其余的相等null(见第二张图片)。我想对此有一个愚蠢的简单解决方案,但这使得不知道更加难以忍受。

我也尝试过使用strcpy,但它不喜欢那样。

有任何想法吗?

输出:

输出:

每次循环后检查数组内容的输出

每次循环后检查数组内容的输出

4

1 回答 1

2

问题出在你的行内

nomtab[a] = nom;

这会将 nomtab[a] 处的指针设置为指向本地数组 nom。但是在每次循环迭代中,您在使用 fscanf 读取文件 Input 时都会覆盖 nom。如果要存储所有字符串,则应复制 nom 并存储它。您可以使用strdup(nom)nom 来制作副本。

顺便说一句,您正在调用 fscanf 而不限制要写入 nom 的字符数。这是一个坏主意。如果文件中有一行太长,那么您将在 nom 中出现缓冲区溢出,从而覆盖您的堆栈。

编辑:这条线看起来很可疑:

char** nomtab = (char **) calloc(nbnoeud, 100*sizeof(char));

我想,你想要的是一个具有 100 个字符长度的 nbnoeud 字符串的数组。您应该将其更改为

char* nomtab = (char *) calloc(nbnoeud, 100*sizeof(char));
strcpy(nomtab[100*a], nom);

或者

char** nomtab = (char **) calloc(nbnoeud, sizeof(char*));
nomtab[a] = strdup(nom);

在第一种情况下,nomtab 是一个包含所有字符串(字符)的大缓冲区,在第二种情况下,nomtab 是一个指向字符串的指针数组,每个字符串都以其他方式分配。在第二种情况下,您需要注意free()分配的字符串缓冲区。

于 2013-04-15T09:50:22.447 回答