C语言读取二进制文件后链表显示随机数据求助
Hey there! Let's break down what's causing those weird random values showing up in your display, and fix that crash with the for loop too.
The Root of the Random Data
Your file reading logic has a critical order issue: right now, you're allocating a new trip node first, adding it to the linked list, and then trying to read data into it. When fread fails (like when you hit the end of the file), you break out of the loop—but that already-allocated node is still stuck at the end of your list, filled with uninitialized garbage memory. That's exactly the random junk you're seeing.
Fixing the File Reading Code
Here's the corrected version of your read function, with comments explaining the fixes:
FILE *fp; if ((fp = fopen("Excursion.bin", "rb")) == NULL) { printf("No info added yet\n"); exit(1); } // First, clear any existing nodes in the list to avoid mixing old and new data trip *temp_cleanup; while (head != NULL) { temp_cleanup = head; head = head->next; free(temp_cleanup); } head = NULL; current = NULL; excursion temp_data; // Read into a temporary struct first while (fread(&temp_data, sizeof(excursion), 1, fp) == 1) { // Only allocate a node if we successfully read data trip *new_node = (trip*)malloc(sizeof(trip)); if (new_node == NULL) { // Always check if malloc succeeded! printf("Memory allocation failed\n"); fclose(fp); exit(1); } // Copy the valid data into the new node memcpy(&new_node->data, &temp_data, sizeof(excursion)); new_node->next = NULL; // Ensure the new node points to nothing initially // Add the node to the linked list if (head == NULL) { head = new_node; current = head; } else { current->next = new_node; current = new_node; } } fclose(fp);
Key fixes here:
- Read first, allocate later: We only create a new node when
freadconfirms it got valid data. No more empty garbage nodes. - Clear existing list: If your program runs the read function multiple times, this prevents old nodes from cluttering up your list.
- Check malloc success: Skipping this can lead to crashes if your program runs out of memory.
- Properly copy data: Using
memcpyensures every field in theexcursionstruct gets copied correctly.
Fixing the For Loop Crash
Your original displayALL with a while loop is fine, but the for loop crash was likely caused by that garbage node at the end of the list having an uninitialized next pointer (pointing to random memory). With the fixed read code, this for loop version will work perfectly:
void displayALL() { for (trip *temp = head; temp != NULL; temp = temp->next) { printf("ID of Excursion is %s\nDuration is %d days\nDate of departure is %s\nThe price is %.2f\n", temp->data.ID, temp->data.duration, temp->data.date, temp->data.price); } }
A Quick Improvement for Writing Data
Just a small tweak to your write function to handle empty lists and clean up properly if an error occurs:
FILE * fp; trip *temp; if ((fp = fopen("Excursion.bin", "wb")) == NULL) { printf("Error opening file"); exit(1); } if (head == NULL) { printf("No excursions to write to file\n"); fclose(fp); return; } for (temp = head; temp != NULL; temp = temp->next) { if (fwrite(&temp->data, sizeof(excursion), 1, fp) != 1) { printf("Error in writing file\n"); fclose(fp); // Don't leave the file open if we exit early exit(1); } } fclose(fp);
With these changes, your linked list should display only valid excursion data, no more random garbage, and both while and for loops will work without crashing.
内容的提问来源于stack exchange,提问作者Scooby Doo

