-3

所以我有这个程序,我从头开始放在一起 c。它来自第 6 章 - 数据结构一章......我的问题是输出显示所有以前列出的条目以及最后输入的标准输入名称。因此,一旦程序几乎两次打印所有内容,就显示所有打印的内容。我很难描述。如果您只是将其复制并粘贴到您机器上的文本编辑器中并运行代码,您就会明白我的意思。

这本书展示了使用 < 重定向工具获取岛屿名称文件的程序。当我尝试这个时,它会打印名字、第二个名字和名字。然后是下一个名字,第二个和第一个名字......然后是下一个名字,第三个,第二个和第一个名字......等等,这取决于有多少个名字。在标准输入中的终端中输入文本时也会发生此行为。

如果我将代码更改为 display(next) 它的工作方式更接近我的预期,但它仍然会打印出一个额外的空白行,并且可能存在内存泄漏

这段代码几乎让我头晕目眩,有人能弄清楚它为什么会这样打印吗?

我会先问 c 讨论板,但我想先问 stackoverflow 并立即得到答案。

我的代码如下。如果将其复制并粘贴到文本编辑器中,它不应看起来像一堵文本墙。

快乐编码。

#include <stdio.h> // basic input output
#include <stdlib.h>  // for obtaining and releasing heap memory malloc and free...
#include <string.h>  // for the stringdup method

typedef struct island {
    char *name;
    char *opens;
    char *closes;
    struct island *next;
} island;

void display(island *madonna);

island* create(char *name);

void release(island *start);

int main()
{
    /* create islands */
    island *start = NULL;
    island *i = NULL;
    island *next = NULL;
    char name[80];
    puts("enter island name...");
    for(; fgets(name, 80, stdin) != NULL; i = next) {
        next = create(name);
        if(start == NULL)
            start = next;
        if (i != NULL)
            i -> next = next;

        display(start);

    }
    release(start);

}

// display method
void display(island *start)
{
    island *i = start;

    if (i == NULL)
        puts("i equals NULL ");

    for(;i != NULL; i = i ->next) {
        printf("Name: %s open: %s-%s\n", i->name, i->opens, i->closes);
    }
}

// create method
island* create(char *name)
{
    island *i = malloc(sizeof(island));
    i->name = strdup(name);
    i->opens = "09:00";
    i->closes = "17:00";
    i->next = NULL;
    return i;
}

// release method
void release(island *start)
{
    island *i = start;
    island *next = NULL;
    for(; i != NULL; i = next) {
        next = i-> next;
        free(i->name); // must free this first because of strdup uses heap memory
        free(i);
    }
}
4

2 回答 2

1

该代码按设计工作(WAD)。它旨在在读取每个条目后打印完整的列表——这就是display(start)循环中的作用。您可以通过回显输入(printf("Read: %s", name);格式中没有换行符,因为名称仍然包含换行符)或printf("Printing list:\n");在调用之前标记显示display()(或两者)来帮助自己。如果您从名称中删除换行符,则需要调整“回声”操作。

学习如何创建有用的诊断信息是一项有价值的技术;关键点之一是确保输出行以换行符结尾,这样您就有很大的机会在打印时看到打印,而不是稍后某个不确定的时间。另一个关键点是打印输入,以便您知道代码在做什么,而不是认为您知道代码在做什么。在每次迭代中打印完整列表也有助于确保正确构建列表。您可以在 SO 上找到未正确构建列表的示例(例如struct 的第一个地址)。如果每次迭代都打印完整的列表,问题会更加明显。

因此,问题似乎在于您的期望与代码的设计目的不匹配。

于 2013-05-06T06:10:35.397 回答
0

“我的问题是输出显示所有以前列出的条目以及最后输入到标准输入的名称。”

 for(;i != NULL; i = i ->next) {
        printf("Name: %s open: %s-%s\n", i->name, i->opens, i->closes);

顺便说一句,您告诉我们您的问题,但您没有告诉我们您的程序应该做什么

于 2013-05-06T05:40:13.337 回答