简体   繁体   English

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

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

As a project, I have to read multiple tabular seperated files (containing x and y coordinates starting from 0,0 at left top) and save the content within a dynamically allocated linked list. 作为一个项目,我必须读取多个表格分隔文件(包含从左上角0,0开始的x和y坐标),并将内容保存在动态分配的链表中。 With a single read, everything is fine, but when I read and try to append the elements of the second file into the list, the items are not appended somehow. 只需一次读取,一切都很好,但是当我阅读并尝试将第二个文件的元素添加到列表中时,不会以某种方式添加项目。

Could someone help me find where the error is and how to fix it? 有人可以帮助我找到错误的位置以及如何解决吗? Am I kind of doing things wrong with the pointers on the list maybe? 我可能对列表上的指针做错了吗?

The structs: 结构:

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;

The function to read and add the elements: 读取和添加元素的功能:

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

Example input file: 输入文件示例:

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

In that input, the first line specifies the amount of lines and rows to use on screen, the next lines where the elements are positioned with the first number in line being the line or x in (x, y). 在该输入中,第一行指定要在屏幕上使用的行数和行数,接下来的几行是元素所在的位置,行中的第一个数字是行或x in(x,y)。

Example Output: 示例输出:

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

when I read and try to append the elements of the second file into the list, the items are not appended somehow. 当我阅读并尝试将第二个文件的元素添加到列表中时,项目不会以某种方式添加。

Look at this code: 看下面的代码:

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

Here you continue until ptr is NULL. 在这里,您继续直到ptr为NULL。 In other words ptr no longer points to an element in the list. 换句话说, ptr不再指向列表中的元素。 You probably wanted: 您可能想要:

    while (ptr->next != NULL) {

and then you want to append new elements using 然后您想使用添加新元素

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

But you have: 但是你有:

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

which means that the new elements won't be appended to the list from readfirst but that you start a new linked list instead. 这意味着新元素不会从readfirst追加到列表,而是您开始一个新的链接列表。

I haven't looked into all details of your code but I think you to change the code to something like: 我没有研究代码的所有细节,但我认为您可以将代码更改为:

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