打印链表时,结构变量未正确保存?

时间:2013-11-05 08:29:09

标签: c switch-statement

我有一个链表,我正在尝试插入一个新节点,这似乎是成功插入我希望它去的节点,但变量一直是NULL。有人能指出我导致这种情况发生的地方吗?

这是打印和插入方法。

void printList(node *head)
{
    node *p;
    p = head;
    if(p->next == NULL)
            printf("No stops currently in the tour.");
    else
    {
            while(p->next != NULL)
            {
                    printf("Tour Stop: %s - Description: %s\n", p->name, p->name);
                    p = p->next;
                            }
    }
}


void insertInOrder(node *head, node *newNode)
{
    printf("What is the stop you want the new stop to come after? Type 'end' to insert at the end of the tour.");
    char key[100];
    scanf("%s", &key);
    getchar();

    node *p;
    p = head->next;
    if(head->next == NULL)
            head->next = newNode;

    else if(key == "end")
    {
            while(p->next != NULL)
                    p = p->next;

            p->next = newNode;
    printf("\nAT 57, newNode->info = %s and newNode->name = %s", newNode->info, newNode->name);
    }

    else
    {
            while(strcmp(p->name, key) != 0)
            {
                    if(p->next == NULL)
                    {
                            printf("Couldn't find the tour stop you requested, inserting at end of tour.");
                            break;
                    }

                    p = p->next;
            }

            p->next = newNode;
    }

这是我用来传递给插入方法的createNewNode方法

node* createNewNode()
{
    node *newNode;
    newNode = malloc(sizeof(struct node));

    printf("Enter the name of the new tour stop.\n");
    char newName[100];
    fgets(newName, sizeof(newName), stdin);
    newNode->name = newName;

    printf("Enter information about the tour stop. Max number of characters you can enter is 1000.\n");
    char newDescription[1000];
    newNode->info = newDescription;
    fgets(newDescription, sizeof(newDescription), stdin);
    return newNode;
}

3 个答案:

答案 0 :(得分:3)

您没有将字符串复制到结构中。您只是将指针复制到createNewNode()

中的局部变量
char newName[100];
fgets(newName, sizeof(newName), stdin);
newNode->name = newName;

这意味着当您稍后访问该存储的指针时,未定义的行为,因为它不再有效。

您需要在结构中包含字符空间,并复制(或只读取)字符串,以便在节点存在时保持分配。

答案 1 :(得分:1)

这段代码存在很多问题,我甚至不知道从哪里开始。

printf("What is the stop you want the new stop to come after? Type 'end' to insert at the end of the tour.");
char key[100];
scanf("%s", &key);
getchar();

如果您绝对需要使用scanf(建议不要)读取字符串,则应在'%s'格式说明符之前添加要读取的最大字符,如scanf(“%99s”,& key)。您应该读取99个字符而不是100个字符,以便空终止不会溢出您的数组。

else if(key == "end")
{
    //code
}

这里不是将key的内容与const char *“end”进行比较,而只是将数组 key 的地址与const char *“end”的地址进行比较,你应该使用 而是strcmp。 (甚至更好strncmp

node* createNewNode()
{
    node *newNode;
    newNode = malloc(sizeof(struct node));

    printf("Enter the name of the new tour stop.\n");
    char newName[100];
    fgets(newName, sizeof(newName), stdin);
    newNode->name = newName;

    printf("Enter information about the tour stop. Max number of characters you can enter is 1000.\n");
    char newDescription[1000];
    newNode->info = newDescription;
    fgets(newDescription, sizeof(newDescription), stdin);
    return newNode;
}

此处新节点的名称和信息指针将指向在返回 createNewNode 的调用后释放的内存。这是未定义的行为,您的程序可能会出现段错或更糟。

您应该将读取缓冲区复制到堆上分配的新缓冲区,并将指针设置为指向它们,或者首先在堆上分配缓冲区。

int newDescriptionLength = strlen(newDescription) + 1; //plus 1 for null termination
char* newDescriptionCopy = malloc(newDescriptionLength);
strncpy(newDescriptionCopy, newDescription, newDescriptionLength);
newNode->info = newDescriptionCopy;

strncpy将确保您的newDescriptionCopy字符串在之后以空值终止 已复制源字符串newDescription的所有字符。

释放节点时应考虑分配的缓冲区。

另外,你应该用fgets读取一个字符,因为提供了准确的计数 允许的字符不会为null终止你的字符串。

您应该在深入研究问题之前解决这些问题,因为您的程序充满了未定义的行为,并且在调试过程中做出假设是不安全的。

答案 2 :(得分:0)

从我所看到的你的代码(你没有打印调用函数或链表的init,如果有的话),看起来你永远不会检查第一个元素(即头部)。所以当列表完成时为空,那么head将指向NULL。因此,使用您的打印功能作为示例,您应该:

void printList(node *head)
{
    node *p;
    p = head;

    // Check if the list contains anything
    if (p == NULL)
    {
        printf("List is empty");
    }
    else
    {
        printf("Tour Stop: %s - Description: %s\n", p->name, p->name); // print first/head element

        // Continue while there are more elements
        while(p->next != NULL)
        {
            printf("Tour Stop: %s - Description: %s\n", p->name, p->name);
            p = p->next;
        }
    }
}

你的插入函数可能是一样的,所以你永远不要插入任何东西吗?

注意:放松在他的回答中也有一个非常有效的观点