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

时间:2018-09-29 04:21:24

标签: c struct linked-list scanf

作为一个项目,我必须读取多个表格分隔文件(包含从左上角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

1 个答案:

答案 0 :(得分:0)

  

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

看下面的代码:

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