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

如何在C语言中实现按分数排序添加条目到文件并保留前5名?

解决方案:按分数排序插入并保留前5名

问题分析

你需要读取文本文件中的分数数据,判断新输入的分数是否能进入前5名,若是则将其按分数降序插入对应位置,最终只保留前5条有效数据。原代码仅实现了内容追加到文件末尾的功能,缺少数据解析、排序和截断逻辑。

实现思路

  • 用结构体统一存储每个用户的姓名与分数,便于数据管理
  • 读取文件中所有现有数据,解析为结构体数组
  • 将新输入的用户信息加入数组
  • 对数组按分数从高到低排序
  • 若用户总数超过5,仅保留排序后的前5条数据
  • 将处理后的结果重新写入文件,覆盖原有内容

修改后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义结构体存储用户姓名和分数
typedef struct {
    char nome[20];
    int pontos;
} Usuario;

// qsort排序的比较函数:按分数降序排列
int compararUsuarios(const void *a, const void *b) {
    Usuario *usuarioA = (Usuario *)a;
    Usuario *usuarioB = (Usuario *)b;
    return usuarioB->pontos - usuarioA->pontos;
}

int main() {
    Usuario usuarios[100]; // 定义足够大的数组存储现有用户
    int totalUsuarios = 0;
    char linha[100];
    char nomeNovo[20];
    int pontosNovo;
    FILE *arquivo;

    // 读取现有数据,文件不存在则直接跳过读取步骤
    arquivo = fopen("dados.txt", "r");
    if (arquivo != NULL) {
        printf("Pontuacao atual:\n");
        while (fgets(linha, sizeof(linha), arquivo) != NULL) {
            // 解析每行"nome=pontos"格式的数据
            if (sscanf(linha, "%[^=]=%d", usuarios[totalUsuarios].nome, &usuarios[totalUsuarios].pontos) == 2) {
                printf("%s", linha);
                totalUsuarios++;
            }
        }
        fclose(arquivo);
    }

    // 获取新用户输入
    printf("\nDigite seu nome e seus pontos (格式: nome pontos):\n");
    scanf("%s %d", nomeNovo, &pontosNovo);

    // 将新用户加入数组
    strcpy(usuarios[totalUsuarios].nome, nomeNovo);
    usuarios[totalUsuarios].pontos = pontosNovo;
    totalUsuarios++;

    // 按分数降序排序
    qsort(usuarios, totalUsuarios, sizeof(Usuario), compararUsuarios);

    // 只保留前5名数据
    if (totalUsuarios > 5) {
        totalUsuarios = 5;
    }

    // 将结果写入文件,覆盖原有内容
    arquivo = fopen("dados.txt", "w");
    if (arquivo == NULL) {
        printf("Erro ao abrir arquivo para escrita!\n");
        return 1;
    }
    for (int i = 0; i < totalUsuarios; i++) {
        fprintf(arquivo, "%s=%d\n", usuarios[i].nome, usuarios[i].pontos);
    }
    fclose(arquivo);

    // 输出更新后的前5名
    printf("\nAtualizacao concluida! Top 5 pontuacoes:\n");
    for (int i = 0; i < totalUsuarios; i++) {
        printf("%d. %s=%d\n", i+1, usuarios[i].nome, usuarios[i].pontos);
    }

    return 0;
}

代码说明

  1. 结构体设计:Usuario结构体统一管理用户的姓名和分数,避免数据分散处理的混乱。
  2. 数据解析:通过sscanf解析文件中nome=pontos格式的行数据,确保和示例格式一致。
  3. 排序实现:利用标准库qsort函数配合自定义比较逻辑,快速实现分数降序排序。
  4. 截断逻辑:排序后若用户数量超过5,自动截断为前5条,保证文件只保留最高的5个分数。
  5. 文件写入:以写入模式(w)打开文件,覆盖原有内容,确保文件始终存储最新的前5名数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:25:20