繁体   English   中英

C:多个文件的结构列表和fscanf

[英]C: struct list & fscanf of multiple files

作为一个项目,我必须读取多个表格分隔文件(包含从左上角0,0开始的x和y坐标),并将内容保存在动态分配的链表中。 只需一次读取,一切都很好,但是当我阅读并尝试将第二个文件的元素添加到列表中时,不会以某种方式添加项目。

有人可以帮助我找到错误的位置以及如何解决吗? 我可能对列表上的指针做错了吗?

结构:

typedef enum{
    BLUME=-1, FREI
}belegung;

typedef struct position{
    int zeile;
    int spalte;
    belegung element;
    struct position* next;
}position;

typedef struct feld{
    int zeilen;
    int spalten;
    int anzBlumen;
    position* positionen;
}feld;

读取和添加元素的功能:

int read(feld* f, char* file){
    FILE* in;
    if((in = fopen(file, "r")) == NULL)
        return -1;


    int count = 0;
    if (f->zeilen == 0 && f->spalten == 0 && f->positionen == NULL)
        count = firstread(in, f);

    else {
        printf("already have flowers\n");
        int a, b;
        int oldS = f->spalten;

        position* ptr = f->positionen; // CAUTION: p = NULL
        while (ptr != NULL) {
            ptr = ptr->next;
            if (ptr != NULL)
                printf("readA: ptr @ %p -> (%d, %d) = %d\n", ptr, ptr->zeile,
                    ptr->spalte, ptr->element);
        }

        // read first line
        if (fscanf(in, "%d\t%d", &a, &b) != EOF) {
            f->zeilen = max(f->zeilen, a);
            f->spalten = oldS + b;
            count++;
        }
        // read first flower


        if (fscanf(in, "%d\t%d", &a, &b) != EOF) {
            ptr = calloc(1, sizeof(position));
            ptr->zeile = a;
            ptr->spalte = b + oldS;
            ptr->element = -1;
            ptr->next = NULL;
            count++;
            printf("Flower: (%d, %d)->(%d, %d) at %p\n", a, b, ptr->zeile,
                    ptr->spalte, ptr);
        }
        // read flower lines
        while (fscanf(in, "%d\t%d", &a, &b) != EOF) {
            ptr->next = calloc(1, sizeof(position));
            ptr = ptr->next;
            ptr->zeile = a;
            ptr->spalte = b + oldS;
            ptr->element = -1;
            ptr->next = NULL;
            printf("Flower: (%d, %d)->(%d, %d) at %p\n", a, b, ptr->zeile,
                    ptr->spalte, ptr);
            count++;
        }

        f->anzBlumen += count - 1;
    }


    printf("Flowerscan done\n");
    // get 'next' to write element in ptr
    preinitFreefeld(f);

    //setFreefeld(f);
    printf("setting up free field done\n");
    fclose(in);
    return count;
}

int firstread(FILE* in, feld* f) {
    int a, b;
    position* p = NULL;

    int count = 0;
    // read first line
    if (fscanf(in, "%d\t%d", &a, &b) != EOF) {
        f->zeilen = a;
        f->spalten = b;
        count++;
    }
    // read first flower
    p = calloc(1, sizeof(position));
    position* ptr = p;
     if (fscanf(in, "%d\t%d", &a, &b) != EOF) {
        ptr->zeile = a;
        ptr->spalte = b;
        ptr->element = BLUME;
        ptr->next = NULL;
        count++;
    }
    f->positionen = p;
    // read flower lines
    while (fscanf(in, "%d\t%d", &a, &b) != EOF) {
        if (ptr->next == NULL)
            ptr->next = calloc(1, sizeof(position));
        ptr = ptr->next;
        ptr->zeile = a;
        ptr->spalte = b;
        ptr->element = BLUME;
        ptr->next = NULL;
        count++;
    }

    f->positionen = p;
    f->anzBlumen = count - 1;
    return count;
}

输入文件示例:

3   5
2   2
2   3
0   0
0   1
2   4
1   4
0   2

在该输入中,第一行指定要在屏幕上使用的行数和行数,接下来的几行是元素所在的位置,行中的第一个数字是行或x in(x,y)。

示例输出:

-1  -1  -1  0   0
0   0   0   0   -1
0   0   -1  -1  -1

当我阅读并尝试将第二个文件的元素添加到列表中时,项目不会以某种方式添加。

看下面的代码:

    position* ptr = f->positionen; // CAUTION: p = NULL
    while (ptr != NULL) {
        ptr = ptr->next;
        if (ptr != NULL)
            printf("readA: ptr @ %p -> (%d, %d) = %d\n", ptr, ptr->zeile,
                ptr->spalte, ptr->element);
    }

在这里,您继续直到ptr为NULL。 换句话说, ptr不再指向列表中的元素。 您可能想要:

    while (ptr->next != NULL) {

然后您想使用添加新元素

        ptr->next = calloc(1, sizeof(position)

但是你有:

    if (fscanf(in, "%d\t%d", &a, &b) != EOF) {
        ptr = calloc(1, sizeof(position));
        ^^^^

这意味着新元素不会从readfirst追加到列表,而是您开始一个新的链接列表。

我没有研究代码的所有细节,但我认为您可以将代码更改为:

if (f->positionen == NULL)    // Only check for pointer being NULL
    count = firstread(in, f);

else {
    printf("already have flowers\n");
    int a, b;
    int oldS = f->spalten;

    position* ptr = f->positionen;
    while (ptr->next != NULL) {    // Check for ptr->next
        ptr = ptr->next;
        // if (ptr != NULL)  Delete this line - not needed anymore
            printf("readA: ptr @ %p -> (%d, %d) = %d\n", ptr, ptr->zeile,
                ptr->spalte, ptr->element);
    }

    // read first line
    if (fscanf(in, "%d\t%d", &a, &b) != EOF) {
        f->zeilen = max(f->zeilen, a);
        f->spalten = oldS + b;
        count++;
    }

    // Delete this block - you already have a "first flower"
    // read first flower
    //if (fscanf(in, "%d\t%d", &a, &b) != EOF) {
    //    ptr = calloc(1, sizeof(position));
    //    ptr->zeile = a;
    //    ptr->spalte = b + oldS;
    //    ptr->element = -1;
    //    ptr->next = NULL;
    //    count++;
    //    printf("Flower: (%d, %d)->(%d, %d) at %p\n", a, b, ptr->zeile,
    //            ptr->spalte, ptr);
    //}

    // read flower lines
    while (fscanf(in, "%d\t%d", &a, &b) != EOF) {
        ptr->next = calloc(1, sizeof(position));
        ptr = ptr->next;
        ptr->zeile = a;
        ptr->spalte = b + oldS;
        ptr->element = -1;
        ptr->next = NULL;
        printf("Flower: (%d, %d)->(%d, %d) at %p\n", a, b, ptr->zeile,
                ptr->spalte, ptr);
        count++;
    }

    f->anzBlumen += count - 1;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM