基于文件流创建单链表的实现问题求助
Fixing Your Linked List Implementation
First, let's reference the struct definition you're working with:
typedef struct List { struct List *next; char *str; int count; } List;
Now, let's tackle your two main questions and fix the issues in your code:
1. Searching the Linked List & Creating Nodes When Not Found
Your current search loop has a critical bug: the trailing semicolon makes the loop run without doing anything, leaving p as NULL when you try to access p->str (which causes a crash). Here's the correct approach:
- Traverse each node starting from the head.
- For each node, compare its string with the token using
strcmp. - If a match is found, increment the count and move to the next token.
- If you reach the end of the list without finding a match, create a new node and add it to the list.
2. Initializing the Head & Linking Nodes Properly
- Start with
headset toNULL(this means the list is empty initially). - When adding the first node, set
headto point to this new node. - For subsequent nodes, traverse to the end of the list (not just the head) and set the last node's
nextpointer to the new node. Alternatively, you can keep atailpointer to avoid traversing the list every time (we'll use this optimized approach in the fixed code).
Fixed Complete Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "C2A6E4_List-Driver.h" #define ARRAY_SIZE 255 /*Define the size of the array*/ List *CreateLinkedList(FILE *fp) { List *head = NULL; List *tail = NULL; // Tail pointer to track the end of the list char tempBuffer[ARRAY_SIZE]; while (fgets(tempBuffer, ARRAY_SIZE, fp) != NULL) { // Remove newline character from fgets if present tempBuffer[strcspn(tempBuffer, "\n")] = '\0'; char *strToken = strtok(tempBuffer, " "); while (strToken != NULL) { List *current = head; int found = 0; // Search for existing node with the same string while (current != NULL) { if (strcmp(current->str, strToken) == 0) { current->count++; found = 1; break; } current = current->next; } if (!found) { // Allocate memory for new node List *newNode = (List *)malloc(sizeof(List)); if (newNode == NULL) { fprintf(stderr, "Failed to allocate memory for node!\n"); exit(EXIT_FAILURE); } // Allocate memory for the string and copy the token newNode->str = (char *)malloc(strlen(strToken) + 1); // +1 for null terminator if (newNode->str == NULL) { fprintf(stderr, "Failed to allocate memory for string!\n"); free(newNode); // Clean up before exiting to avoid leaks exit(EXIT_FAILURE); } strcpy(newNode->str, strToken); newNode->count = 1; newNode->next = NULL; // New node is the last one, so next is NULL // Add to the list if (head == NULL) { // List is empty, set head and tail to new node head = newNode; tail = newNode; } else { // Append to the end of the list using tail pointer tail->next = newNode; tail = newNode; // Update tail to the new last node } } strToken = strtok(NULL, " "); } } return head; }
Key Improvements Explained
- Fixed Search Logic: Replaced the empty for loop with a proper traversal that checks each node's string, avoiding null pointer dereferences.
- Correct String Copy: Used
strcpyto copy the actual string content instead of copying pointer addresses (your originalmemcpywas incorrect here). - Tail Pointer Optimization: Added a
tailpointer to avoid traversing the entire list every time we add a new node, making the code more efficient. - Newline Handling: Added
strcspnto remove the newline character thatfgetsincludes (this prevents unexpected newlines in your stored strings). - Cleaner Memory Error Handling: If string allocation fails, we free the already allocated node before exiting to avoid memory leaks.
内容的提问来源于stack exchange,提问作者David Salvador
相关产品推荐
相关产品推荐

