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

如何用C++管理并排序TXT文件中的16208条寄存器数据?

C++处理TXT文件排序与搜索解决方案

核心结论:不用手动实现动态扩容数组

C++标准库的std::vector就是现成的动态扩容容器,完全能替代手动管理的数组,不用自己写扩容逻辑,直接用就行。

步骤拆解:读取、排序、搜索全流程

1. 定义记录结构(推荐)

把每行寄存器记录封装成结构体,方便后续操作,比如假设每行包含日期和其他内容:

struct Registro {
    std::string fecha; // 假设日期是排序/搜索的关键字
    std::string contenido; // 存储整行内容,也可以拆分其他字段
};

2. 修改CArchivo类,用std::vector存储数据

在头文件中添加容器成员和新方法:

#pragma once
#include <vector>
#include <string>
#include <algorithm> // 用于std::sort

class CArchivo{
public:
    errno_t error;
    FILE* archivo;
    std::vector<Registro> registros; // 存储所有记录的容器

    void abrirArchivo(const char nombreArchivo[15]);
    void cerrarArchivo();
    void imprimirArchivo();
    void leerTodosLosRegistros(); // 新增:读取所有记录到vector
    void ordenarRegistros();
    void guardarRegistros();
    void buscarRegistros(std::string fechaInicial, std::string fechaFinal );
    int contarRegistros();

    CArchivo();
    ~CArchivo();
};

3. 实现读取记录的方法

替换原有计数和读取逻辑,直接把数据存入vector:

void CArchivo::leerTodosLosRegistros() {
    if (error != 0) {
        printf("Error en la apertura del archivo");
        return;
    }
    registros.clear();
    char buffer[75];
    // 用fgets返回值判断,比feof更可靠,避免多读空行
    while (fgets(buffer, 75, archivo) != nullptr) {
        std::string linea(buffer);
        Registro reg;
        reg.contenido = linea;
        // 假设日期是前10位,比如"2024-05-20...",按需调整
        reg.fecha = linea.substr(0, 10);
        registros.push_back(reg);
    }
    // 重置文件指针到开头,方便后续操作
    fseek(archivo, 0, SEEK_SET);
}

4. 实现排序功能

利用标准库std::sort,自定义排序规则:

void CArchivo::ordenarRegistros() {
    if (registros.empty()) {
        printf("No hay registros para ordenar\n");
        return;
    }
    // 按日期升序排序,可修改规则适配你的需求
    std::sort(registros.begin(), registros.end(), [](const Registro& a, const Registro& b) {
        return a.fecha < b.fecha;
        // 如果按整行内容排序,替换为:return a.contenido < b.contenido;
    });
    printf("Registros ordenados exitosamente\n");
}

5. 实现日期范围搜索

排序后可用二分查找提高效率,也可以直接遍历:

void CArchivo::buscarRegistros(std::string fechaInicial, std::string fechaFinal) {
    if (registros.empty()) {
        printf("No hay registros para buscar\n");
        return;
    }
    printf("Registros en rango %s a %s:\n", fechaInicial.c_str(), fechaFinal.c_str());
    
    // 高效二分查找版(适合大数据量)
    auto it_inicio = std::lower_bound(registros.begin(), registros.end(), fechaInicial,
        [](const Registro& reg, const std::string& fecha) {
            return reg.fecha < fecha;
        });
    auto it_fin = std::upper_bound(registros.begin(), registros.end(), fechaFinal,
        [](const std::string& fecha, const Registro& reg) {
            return fecha < reg.fecha;
        });
    for (auto it = it_inicio; it != it_fin; ++it) {
        printf("%s", it->contenido.c_str());
    }

    // 简单遍历版(适合小数据量)
    // for (const auto& reg : registros) {
    //     if (reg.fecha >= fechaInicial && reg.fecha <= fechaFinal) {
    //         printf("%s", reg.contenido.c_str());
    //     }
    // }
}

6. 实现保存排序后的数据

void CArchivo::guardarRegistros() {
    FILE* archivoSalida;
    errno_t err = fopen_s(&archivoSalida, "registros_ordenados.txt", "w");
    if (err != 0) {
        printf("Error al abrir archivo de salida\n");
        return;
    }
    for (const auto& reg : registros) {
        fprintf(archivoSalida, "%s", reg.contenido.c_str());
    }
    fclose(archivoSalida);
    printf("Registros guardados exitosamente\n");
}

原代码问题修正

  • feof误用:do-while(feof)会导致多读一次空行,改用while(fgets(...) != nullptr)判断更准确。
  • 文件指针重置:读取或计数后,文件指针会停在末尾,需用fseek(archivo, 0, SEEK_SET)重置到开头。
  • 混合IO:尽量统一用C++的std::ifstream/std::ofstream,比C风格的FILE*更安全简洁。

完整调用示例

int main() {
    CArchivo arch;
    arch.abrirArchivo("tu_archivo.txt");
    arch.leerTodosLosRegistros();
    arch.ordenarRegistros();
    arch.buscarRegistros("2024-01-01", "2024-01-31");
    arch.guardarRegistros();
    arch.cerrarArchivo();
    return 0;
}

内容的提问来源于stack exchange,提问作者Josafat Gs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:50:25