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:
- Broken Parsing Logic: Your word-by-word parsing with
wordNumhas 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
lengthOfFiletwice for space-containing pairs, making it larger than the actual number of nodes in the list. WhenprintListloops forlengthOfFiletimes, it eventually accesses anullptr, triggering a segfault.
- The condition
- Useless
appendFunction: Theappendfunction creates a node but never links it to the list (memory leak), and calling bothappendandaddInOrdercreates 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:
- Simplified Parsing: Instead of tracking
wordNum, we directly read pairs ofletterandnumusingss >> letter >> num. This correctly handles all token types (spaces, punctuation, letters) and ensures each pair is processed once. - Numeric Comparison: In
addInOrder, we convert string numbers to integers withstoi()to compare their actual numeric values, fixing the sorting issue for multi-digit numbers. - Removed
append: We eliminated the brokenappendfunction and only useaddInOrderto insert nodes, avoiding unnecessary memory leaks. - Safer Printing:
printListnow loops whileptris notnullptrinstead of relying onlengthOfFile, preventing segfaults even if the count is incorrect. - Memory Cleanup: Added a call to
deleteListinmainto free all allocated nodes, preventing memory leaks.
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

