【问题标题】:C: struct list & fscanf of multiple filesC:多个文件的struct list & fscanf
【发布时间】:2019-03-05 00:38:51
【问题描述】:

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

示例输出:

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

【问题讨论】:

  • 好奇:fscanf(in, "%d\t%d", &a, &b) 可能返回 2(期望)、1(意外)或 EOF(文件结束),为什么代码与 EOF 比较而不是 2?
  • 好吧,我没有检查任何其他可能性,但是,当我在控制台上打印ab 时,程序确实成功地读取了它们。它只是没有将其分配给position,或者我正在覆盖相同的位置?我“添加”的元素从未出现在列表中

标签: c struct linked-list scanf


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 2014-11-10
    • 1970-01-01
    • 2014-05-26
    相关资源
    最近更新 更多