竞赛结果文件读取异常:fscanf失效疑与换行相关求排查
Hey there! Let's break down what's going on with your code—first off, the newline characters aren't actually the issue with fscanf here. Let's walk through the real problems and fix them step by step.
Why Newlines Aren't Breaking fscanf
The %s format specifier in fscanf automatically skips any leading whitespace (including newlines, spaces, and tabs) before reading a sequence of non-whitespace characters. Your input data—whether it's all on one line or split across multiple lines—will be read correctly as long as names and scores are separated by whitespace. So the newline theory can be ruled out right away.
The Real Issues in Your Code
Your problem comes from the sorting logic, not the file reading part:
You're only swapping names, not scores
When you swapplayers[t].nameandplayers[u].name, you leave their scores untouched. This means after sorting, names and their corresponding scores will be completely mismatched, making it look like the file read failed when it actually didn't.Inefficient and incorrect sorting loop
Your nested loops compare every pair of elements multiple times, which leads to unnecessary swaps and unpredictable sorting results. A standard bubble sort (or any proper sorting algorithm) focuses on adjacent elements or uses a more logical traversal to avoid redundant work.
Fixed Code
Here's the corrected version of your code, with the sorting logic fixed to swap entire Contest structs and use a proper bubble sort:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct contest { char name[25]; int score; } Contest; int main(int argc, const char * argv[]) { Contest players[100]; FILE *fp; fp = fopen("contest.txt", "r"); if(fp == NULL) { fprintf(stderr, "Error: failed to open the file\n"); exit(EXIT_FAILURE); } int cnt = 0; // File reading works correctly here—newlines don't affect it while(fscanf(fp, "%s %d", players[cnt].name, &players[cnt].score) != EOF) { ++cnt; } // Proper bubble sort: swap entire structs, compare adjacent elements for(int t = 0; t < cnt - 1; ++t) { for(int u = 0; u < cnt - t - 1; ++u) { // Sort in alphabetical order (case-insensitive) if(strcasecmp(players[u].name, players[u+1].name) > 0) { Contest temp = players[u]; players[u] = players[u+1]; players[u+1] = temp; } } } // Print the sorted results for(int t = 0; t < cnt; ++t) { fprintf(stdout, "Name : %s Score : %d\n", players[t].name, players[t].score); } fclose(fp); return 0; }
Quick Test Tip
To confirm the file reading works as expected, add a loop right after reading the data to print out the original, unsorted entries. This will let you verify that fscanf is correctly pulling names and scores from the file before sorting messes things up.
内容的提问来源于stack exchange,提问作者Louis Deidda

