错误遍历和打印单独链接的列表在C中



丢失的菜单,试图按线路读取文件,即"一个","两个","三",并在有序的链接列表中添加相同(我相信我有在职的)。但是,我无法找出我的traverse_and_print列表函数的语法/逻辑(并且不理解 *(转到此处获取值),&(获取地址)和 -> - 请访问https://repl.it/@michaelb4/deafeneatreasuredmathematics

// A complete working C program to demonstrate all insertion methods 
// from https://www.geeksforgeeks.org/linked-list-set-2- inserting-a-node/
#include <stdio.h> 
#include <stdlib.h> 
#include<string.h>
// Create structure for a linked list node 
struct Node 
{ 
    const char *data; 
    struct Node *next; 
}; 
struct Node *head;
// Given a reference (pointer to pointer) to the head of a list and a char*, appends a new node at the end
void append(struct Node** head_ref, const char *new_data) 
{ 
    // 1. allocate node
    struct Node* new_node = (struct Node*) malloc(sizeof(struct Node)); 
    struct Node *last = *head_ref;  // used in step 5
    // 2. put in the data
    new_node-> data  = new_data; 
    // 3. Set new_node.next to Null, as it will be inserted at tail of list 
    new_node -> next = NULL;
    // 4. If the Linked List is empty, then make the new node as head
    if (*head_ref == NULL) 
    { 
        *head_ref = new_node;
        //printf("headn");
        printf("%s", new_node -> data); 
        return; 
    } 
    // 5. Else traverse till the last node
    while (last -> next != NULL)  
        last = last -> next;
        printf("%s", new_node -> data); 
    // 6. Change the next of last node, have last node point to one just inserted, the new node at the end of the list, tail 
    last -> next = new_node; 
    return; 
} 
void traverse_and_printList(head){
    struct Node* current = (struct Node*) malloc(sizeof(struct Node));
    current = head;
    while (head -> next != NULL)
        printf("%s", current -> data);
        current -> next = current;
}
/* Driver program to test above functions*/
int main() 
{ 
    // set up a file point to File to be opened
    FILE* fp;
    // holds contents of each line/word 
    char buffer[255]; 
    fp = fopen("words.txt", "r");
    if (fp == NULL)
    {
        fprintf(stderr, "Could not open infile"); 
        return 2;
    }
    /* create an empty node */
    struct Node* head = NULL; 
    int counter = 0;
    char *head_value[255]; 
    while(fgets(buffer, 255, (FILE*) fp)){
        //printf("%s", buffer);
        append(&head, buffer);
    }
    fclose(fp);
    traverse_and_printList(head);
    printf("n");
    return 0; 
}

您对current指针使用的目的感到困惑。

首先,您无需为此分配内存。您不是要存储任何新的东西。current指针只是一个值,它可以帮助您在列表中的项目上移动。

第二,您不应该修改列表的数据。线current->next = current是伪造的。它修改列表创建一个周期。不好。

第三,您的缩进建议您的while环包含两个单独的语句,但是周围没有块范围(即 { ... })。因此,只有第一个语句将是循环的一部分。

最后,关于样式的观点。请不要将空格放在->周围。虽然编译器不在乎,但它使您的代码很难阅读。

正确穿越列表与此一样简单:

for(struct Node* current = head; current != NULL; current = current->next)
{
    printf("%sn", current->data);
}

它在我看来就像您的'traverse and Print'功能有问题。您有:

void traverse_and_printList(head){
    struct Node* current = (struct Node*) malloc(sizeof(struct Node));
    current = head;
    while (head -> next != NULL)
        printf("%s", current -> data);
        current -> next = current;
}
  • 现代的海湾合作委员会会警告您误导凹痕 - current->next = current;线不受while环路控制(C是 python!)。
  • 在循环中测试head->current是错误的;您应该测试的是current->head
  • 作为样式的点,点.和箭头->操作员绑定非常紧密,不应在其两侧的两侧都有空格。
  • 打印功能不应进行节点的任何分配。

由于您从函数定义行中省略了类型信息,因此head被解释为int(使用预标准C的规则,C90必须允许,以便接受它的机会)使用未配置的编译器编译以抱怨前C99代码。这是21世纪;您不应使用30岁的符号。计算如何至少指定C99以及如何获取警告。使用GCC,这将符合-std=c99 -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes的线路;我也使用 -Wextra,而且通常还有更多选项。

void traverse_and_printList(struct Node *head)
{
    struct Node *current = head;
    while (current->next != NULL)
    {
        printf("%s", current->data);
        current->next = current;
    }
}

尤其是在调试时,我可能会使用以下格式更像以下格式,围绕着标记的数据(我选择了[[]],但选择是您的),因为它可以揭示问题(例如不需要的'r'线的末端):

printf("[[%s]]n", current->data);

我也可能会打印指针:

printf("C %p N %p [[%s]]n", (void *)current, (void *)current->next, current->data);

您可能更喜欢更多的详细符号(Current而不是C; Next而不是N),但是紧凑型也具有其优点。

警告:修订的代码尚未在编译器附近。

最新更新