C++链表实现房间预订系统的代码优化与问题解决
Hey there! Let's break down your problems one by one and refactor your code to make it clean, functional, and meet your requirements—showing only available rooms in the menu and removing booked ones, plus fixing those bugs you ran into.
First: Fixing the "pointer vs integer" comparison error
Your initial mistake was comparing an array pointer to an integer. When you wrote current->single_room == x, current->single_room is the memory address of the array (not an individual room number), hence the compiler error. To fix this, you need to loop through the array elements to check if any match x:
// Instead of this: // if (current->single_room == x) // Do this: bool match = false; for (int i = 0; i < 5; i++) { if (current->single_room[i] == x) { match = true; break; } } found = match;
But honestly, this array-based approach was setting you up for messy code anyway—let's redesign the data structure properly.
Core Issue: Your Linked List Node Design Is Overcomplicated
Right now, each node holds four different room numbers (one for each type), which doesn't make sense. A node should represent either a single room or a single reservation, not a mix of all room types. Let's restructure things:
Step 1: Define Clear Data Structures
#include <iostream> #include <fstream> #include <string> #include <windows.h> // Use an enum for room types to avoid magic numbers enum RoomType { SINGLE, DOUBLE, DELUXE, PRESIDENT }; // Represents a single hotel room struct Room { int number; RoomType type; bool isBooked; Room* next; // For linked list of rooms }; // Represents a guest's reservation struct Reservation { std::string guestName; int phoneNumber; int checkInDate; int nights; int pax; int roomNumber; // Links to the booked room Reservation* next; // For linked list of reservations };
Step 2: Simplify the Reservation Class
Now the class will manage two separate linked lists: one for all rooms, one for active reservations. This keeps concerns separated and makes code easier to maintain.
class HotelReservationSystem { private: Room* roomList; Reservation* reservationList; // Helper function to create a new room node Room* createRoom(int num, RoomType type) { Room* newRoom = new Room; newRoom->number = num; newRoom->type = type; newRoom->isBooked = false; newRoom->next = nullptr; return newRoom; } // Helper function to create a new reservation node Reservation* createReservation(const std::string& name, int phone, int date, int nights, int pax, int roomNum) { Reservation* newRes = new Reservation; newRes->guestName = name; newRes->phoneNumber = phone; newRes->checkInDate = date; newRes->nights = nights; newRes->pax = pax; newRes->roomNumber = roomNum; newRes->next = nullptr; return newRes; } public: HotelReservationSystem() : roomList(nullptr), reservationList(nullptr) { // Initialize all rooms once in the constructor initializeRooms(); } ~HotelReservationSystem() { // Clean up room list while (roomList != nullptr) { Room* temp = roomList; roomList = roomList->next; delete temp; } // Clean up reservation list while (reservationList != nullptr) { Reservation* temp = reservationList; reservationList = reservationList->next; delete temp; } } // Initialize all hotel rooms void initializeRooms() { // Add single rooms (101-105) for (int i = 101; i <= 105; i++) { Room* newRoom = createRoom(i, SINGLE); newRoom->next = roomList; roomList = newRoom; } // Add double rooms (201-204) for (int i = 201; i <= 204; i++) { Room* newRoom = createRoom(i, DOUBLE); newRoom->next = roomList; roomList = newRoom; } // Add deluxe suites (301-302) for (int i = 301; i <= 302; i++) { Room* newRoom = createRoom(i, DELUXE); newRoom->next = roomList; roomList = newRoom; } // Add president suites (401) Room* presRoom = createRoom(401, PRESIDENT); presRoom->next = roomList; roomList = presRoom; } // Show menu options void showMenu() { std::cout << "\n=== Hotel Reservation System ===" << std::endl; std::cout << "1. Book a Reservation" << std::endl; std::cout << "2. Update a Reservation" << std::endl; std::cout << "3. Delete a Reservation" << std::endl; std::cout << "4. Display All Reservations" << std::endl; std::cout << "5. View Available Rooms" << std::endl; std::cout << "6. Exit" << std::endl; std::cout << "Enter your choice: "; } // Display available rooms grouped by type void displayAvailableRooms() { std::cout << "\n=== Available Rooms ===" << std::endl; // Single rooms std::cout << "Single Rooms: "; Room* current = roomList; bool hasAvailable = false; while (current != nullptr) { if (current->type == SINGLE && !current->isBooked) { std::cout << current->number << " "; hasAvailable = true; } current = current->next; } if (!hasAvailable) std::cout << "None"; std::cout << std::endl; // Double rooms std::cout << "Double Rooms: "; current = roomList; hasAvailable = false; while (current != nullptr) { if (current->type == DOUBLE && !current->isBooked) { std::cout << current->number << " "; hasAvailable = true; } current = current->next; } if (!hasAvailable) std::cout << "None"; std::cout << std::endl; // Deluxe suites std::cout << "Deluxe Suites: "; current = roomList; hasAvailable = false; while (current != nullptr) { if (current->type == DELUXE && !current->isBooked) { std::cout << current->number << " "; hasAvailable = true; } current = current->next; } if (!hasAvailable) std::cout << "None"; std::cout << std::endl; // President suites std::cout << "President Suites: "; current = roomList; hasAvailable = false; while (current != nullptr) { if (current->type == PRESIDENT && !current->isBooked) { std::cout << current->number << " "; hasAvailable = true; } current = current->next; } if (!hasAvailable) std::cout << "None"; std::cout << std::endl; } // Book a room void bookReservation() { displayAvailableRooms(); int roomNum; std::cout << "\nEnter the room number you want to book: "; std::cin >> roomNum; std::cin.ignore(); // Clear newline from input buffer // Check if room exists and is available Room* targetRoom = roomList; bool roomFound = false; while (targetRoom != nullptr) { if (targetRoom->number == roomNum) { roomFound = true; if (targetRoom->isBooked) { std::cout << "Sorry, this room is already booked!" << std::endl; return; } break; } targetRoom = targetRoom->next; } if (!roomFound) { std::cout << "Invalid room number!" << std::endl; return; } // Get guest details std::string name; int phone, date, nights, pax; std::cout << "Enter guest name: "; std::getline(std::cin, name); std::cout << "Enter phone number: +"; std::cin >> phone; std::cout << "Enter check-in date (YYYYMMDD): "; std::cin >> date; std::cout << "Enter number of nights: "; std::cin >> nights; std::cout << "Enter number of guests: "; std::cin >> pax; // Create reservation Reservation* newRes = createReservation(name, phone, date, nights, pax, roomNum); newRes->next = reservationList; reservationList = newRes; // Mark room as booked targetRoom->isBooked = true; // Save to file std::ofstream file("Guest info.txt", std::ios::out | std::ios::app); if (file.is_open()) { file << "Room: " << roomNum << ", Name: " << name << ", Phone: +" << phone << ", Check-in: " << date << ", Nights: " << nights << ", Guests: " << pax << std::endl; file.close(); std::cout << "Reservation booked successfully! Details saved to file." << std::endl; } else { std::cout << "Error: Could not open file to save reservation." << std::endl; } } // Update a reservation void updateReservation() { int roomNum; std::cout << "Enter the room number of the reservation to update: "; std::cin >> roomNum; std::cin.ignore(); // Find the reservation Reservation* currentRes = reservationList; bool resFound = false; while (currentRes != nullptr) { if (currentRes->roomNumber == roomNum) { resFound = true; break; } currentRes = currentRes->next; } if (!resFound) { std::cout << "No reservation found for this room number!" << std::endl; return; } // Update details std::cout << "Current guest name: " << currentRes->guestName << std::endl; std::cout << "Enter new guest name (press enter to keep current): "; std::string newName; std::getline(std::cin, newName); if (!newName.empty()) currentRes->guestName = newName; std::cout << "Current phone number: +" << currentRes->phoneNumber << std::endl; std::cout << "Enter new phone number (0 to keep current): "; int newPhone; std::cin >> newPhone; if (newPhone != 0) currentRes->phoneNumber = newPhone; std::cout << "Reservation updated successfully!" << std::endl; } // Display all reservations void displayReservations() { std::cout << "\n=== All Reservations ===" << std::endl; if (reservationList == nullptr) { std::cout << "No active reservations." << std::endl; return; } Reservation* current = reservationList; int count = 1; while (current != nullptr) { std::cout << "Reservation " << count << ":" << std::endl; std::cout << "Room: " << current->roomNumber << ", Guest: " << current->guestName << ", Phone: +" << current->phoneNumber << std::endl; std::cout << "Check-in: " << current->checkInDate << ", Nights: " << current->nights << ", Guests: " << current->pax << "\n" << std::endl; current = current->next; count++; } } };
Key Improvements & Fixes
- No more pointer-integer errors: We're now comparing room numbers (integers) directly, not array pointers.
- Cleaner data separation: Rooms and reservations are managed in separate linked lists, so each node has a single responsibility.
- Available rooms only: The
displayAvailableRooms()function filters out booked rooms automatically, so your menu shows exactly what's free. - Reduced redundancy: Helper functions (
createRoom,createReservation) eliminate duplicate node creation code. - Fixed initialization: All rooms are initialized once in the constructor, no need for four separate
InitializeValue_*functions. - Logical update flow: The
updateReservation()function properly finds the reservation first, then lets the user edit details without invalid return statements.
How to Use the Refactored Code
Just add a main function to run the system:
int main() { HotelReservationSystem system; int choice; do { system.showMenu(); std::cin >> choice; std::cin.ignore(); // Clear input buffer switch(choice) { case 1: system.bookReservation(); break; case 2: system.updateReservation(); break; case 3: // Implement delete reservation if needed std::cout << "Delete feature coming soon!" << std::endl; break; case 4: system.displayReservations(); break; case 5: system.displayAvailableRooms(); break; case 6: std::cout << "Exiting system..." << std::endl; break; default: std::cout << "Invalid choice, please try again." << std::endl; } system("pause"); // For Windows, to keep console open } while (choice != 6); return 0; }
内容的提问来源于stack exchange,提问作者Cheeseburger

