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

C++链表读取文件并按数字排序问题求助

Analysis of Your Issues & Fixes

Let's break down the two main problems and their root causes, then provide the corrected code.

Issue 1: Missing Entries & Segmentation Fault

Root Causes:

  1. Broken Parsing Logic: Your word-by-word parsing with wordNum has critical logical errors:
    • The condition else if (word != "!" or word != ".") is always true (any word will fail at least one of these checks). This leads to incorrect handling of non-alphabetic, non-punctuation tokens like spaces.
    • You increment lengthOfFile twice for space-containing pairs, making it larger than the actual number of nodes in the list. When printList loops for lengthOfFile times, it eventually accesses a nullptr, triggering a segfault.
  2. Useless append Function: The append function creates a node but never links it to the list (memory leak), and calling both append and addInOrder creates two nodes per pair (only one is added to the list).

Issue 2: Incorrect Sorting in addInOrder

Root Cause:

You’re comparing numeric values as strings (lexicographical order). For example, "10" < "2" lexicographically, but numerically 10 > 2. This leads to wrong positions for multi-digit numbers.


Fixed Code

#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <ctype.h>
using namespace std;

struct ListNode {
    string letter;
    string num;
    ListNode *next;
};

void addInOrder(ListNode *&h, string l, string n);
void printList(ListNode *h);
void deleteList(ListNode *&h);

int main() {
    string letter;
    string num;
    int lengthOfFile = 0;
    const string FILENAME = "file link"; // Replace with your actual file path
    ifstream inFile(FILENAME);
    ListNode *head = nullptr;

    if (inFile) {
        string line;
        while (getline(inFile, line)) {
            stringstream ss(line);
            // Parse line as pairs of (letter, number) directly
            while (ss >> letter >> num) {
                // Optional: Print debug info for each pair
                if (letter == " ") {
                    cout << "letter: [space], number: " << num << endl;
                } else if (letter == "!" || letter == ".") {
                    cout << "letter: " << letter << ", number: " << num << endl;
                } else if (isalpha(letter[0])) {
                    cout << "letter: " << letter << ", number: " << num << endl;
                }
                lengthOfFile++;
                addInOrder(head, letter, num);
            }
        }
        inFile.close();
    } else {
        cerr << "Error opening file!" << endl;
        return 1;
    }

    cout << "\nTotal entries: " << lengthOfFile << endl;
    cout << "\nSorted list:\n";
    printList(head);

    // Clean up allocated memory
    deleteList(head);
    return 0;
}

void addInOrder(ListNode *&h, string l, string n) {
    ListNode *newNode = new ListNode;
    newNode->letter = l;
    newNode->num = n;
    newNode->next = nullptr;

    if (h == nullptr) {
        h = newNode;
        return;
    }

    // Convert string numbers to integers for proper numeric comparison
    int new_num = stoi(n);
    ListNode *prev = nullptr;
    ListNode *curr = h;

    // Find insertion point based on numeric value
    while (curr != nullptr && stoi(curr->num) < new_num) {
        prev = curr;
        curr = curr->next;
    }

    // Insert at the beginning of the list
    if (prev == nullptr) {
        newNode->next = h;
        h = newNode;
    } else { // Insert between prev and curr, or at the end
        prev->next = newNode;
        newNode->next = curr;
    }
}

void printList(ListNode *h) {
    ListNode *ptr = h;
    // Loop until we reach the end of the list (safer than relying on lengthOfFile)
    while (ptr != nullptr) {
        cout << ptr->letter << " " << ptr->num << endl;
        ptr = ptr->next;
    }
}

void deleteList(ListNode *&h) {
    ListNode *temp;
    while (h != nullptr) {
        temp = h;
        h = h->next;
        delete temp;
    }
}

Key Fixes Explained:

  1. Simplified Parsing: Instead of tracking wordNum, we directly read pairs of letter and num using ss >> letter >> num. This correctly handles all token types (spaces, punctuation, letters) and ensures each pair is processed once.
  2. Numeric Comparison: In addInOrder, we convert string numbers to integers with stoi() to compare their actual numeric values, fixing the sorting issue for multi-digit numbers.
  3. Removed append: We eliminated the broken append function and only use addInOrder to insert nodes, avoiding unnecessary memory leaks.
  4. Safer Printing: printList now loops while ptr is not nullptr instead of relying on lengthOfFile, preventing segfaults even if the count is incorrect.
  5. Memory Cleanup: Added a call to deleteList in main to free all allocated nodes, preventing memory leaks.

内容的提问来源于stack exchange,提问作者sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:32:15