You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于文件流创建单链表的实现问题求助

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 head set to NULL (this means the list is empty initially).
  • When adding the first node, set head to 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 next pointer to the new node. Alternatively, you can keep a tail pointer 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 strcpy to copy the actual string content instead of copying pointer addresses (your original memcpy was incorrect here).
  • Tail Pointer Optimization: Added a tail pointer to avoid traversing the entire list every time we add a new node, making the code more efficient.
  • Newline Handling: Added strcspn to remove the newline character that fgets includes (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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:40:29