C语言中将文本文件转为单链表时插入操作的头结点更新问题
Hey, I notice your linked list works fine when populating it from an array, but you're hitting head node update problems when reading from a file. This is a common issue, usually tied to how you handle the head pointer, string memory management, or file reading logic. Let's walk through the likely problems and fix them step by step.
First, Spot the Potential Issues in Your Code
Your createnode function looks incomplete, but even from what's there, I can pick out a few critical pitfalls:
- String Memory Mismanagement: If you're directly assigning
wrdtonode->word, andwrdpoints to a stack buffer (like a local char array used for file reading), all nodes will end up pointing to the same memory. This means later reads will overwrite earlier strings, or you'll end up with dangling pointers. - Incorrect Head Pointer Passing: If your file-reading function takes a
node* headinstead of anode** head, any changes to the head node inside the function won't affect the original pointer outside. That's a classic pass-by-value vs pass-by-reference mistake. - Flawed File Reading Logic: You might not be handling EOF correctly, or you're not skipping whitespace (like newlines) when reading, leading to empty or duplicate nodes.
Fixed Full Code
Here's a complete, working version of your code with all issues addressed:
#include <string.h> #include <stdio.h> #include <stdlib.h> // Define the linked list node structure typedef struct node { char *word; struct node *next; } node; // Create a new node with properly allocated string memory node *createnode(char *wrd) { node *temp1 = malloc(sizeof(node)); if (!temp1) { perror("Failed to allocate memory for node"); exit(EXIT_FAILURE); } // Allocate separate memory for the string to avoid overwrites temp1->word = malloc(strlen(wrd) + 1); if (!temp1->word) { perror("Failed to allocate memory for string"); free(temp1); exit(EXIT_FAILURE); } strcpy(temp1->word, wrd); temp1->next = NULL; return temp1; } // Build linked list from a file: use double pointer to modify the head void buildListFromFile(node **head, const char *filename) { FILE *fp = fopen(filename, "r"); if (!fp) { perror("Couldn't open the file"); exit(EXIT_FAILURE); } char buffer[256]; // Buffer for reading words (adjust size if needed) node *current = NULL; // Read words until end of file (skips whitespace automatically) while (fscanf(fp, "%s", buffer) != EOF) { node *newNode = createnode(buffer); if (!*head) { // First node: initialize head and current pointer *head = newNode; current = newNode; } else { // Append to the end of the list current->next = newNode; current = newNode; } } fclose(fp); } // Helper function to print the list void printList(node *head) { node *temp = head; while (temp) { printf("%s ", temp->word); temp = temp->next; } printf("\n"); } // Helper function to free all memory used by the list void freeList(node *head) { node *temp; while (head) { temp = head; head = head->next; free(temp->word); free(temp); } } int main() { node *head = NULL; buildListFromFile(&head, "words.txt"); printList(head); freeList(head); return 0; }
Key Fixes Explained
Independent String Memory:
Instead of assigning the input string directly tonode->word, we allocate new memory for each string usingmalloc(strlen(wrd) + 1)(the +1 is for the null terminator\0). This ensures each node's string is stored in its own memory block, so later reads won't overwrite previous data.Double Pointer for Head Node:
ThebuildListFromFilefunction takes anode** head(a pointer to the head pointer). This lets us modify the original head pointer inmaindirectly. If we only passed anode*, we'd be working with a copy of the pointer, and changes wouldn't reflect outside the function.Robust File Reading:
Usingfscanf(fp, "%s", buffer)reads one word at a time, automatically skipping any whitespace (spaces, newlines, tabs). If you need to read full lines instead, you can usefgets—just remember to trim the newline character from the buffer before creating the node.Memory Safety:
We added error checking for allmalloccalls to handle memory allocation failures gracefully, and afreeListfunction to clean up all allocated memory (both nodes and strings) to prevent leaks.
Testing Tips
Make sure your input file (words.txt) has words separated by whitespace, like:
hello world foo bar test
When you run the program, it should print all the words in order without any issues.
内容的提问来源于stack exchange,提问作者Diksha

