#pragma once #include "stdafx.h" #include #include /** * @brief TSV(Tab分隔值)数据解析器 * * 独立的 TSV 解析工具类,可被其他模块复用 * 负责将 TSV 格式的文本数据解析为结构化的表格数据 */ class TsvParser { public: /** * @brief 表格数据结构 * * 存储解析后的表格数据,包括列头和数据行 */ struct TableData { std::vector headers; // 列头 std::vector> rows; // 数据行 std::map columnIndexMap; // 列名到索引的映射(不区分大小写) /** * @brief 获取列索引 * @param columnName 列名(不区分大小写) * @return 列索引,未找到返回 -1 */ int GetColumnIndex(const CString& columnName) const; /** * @brief 获取字段值 * @param row 行对象 * @param columnName 列名 * @return 字段值(已 Trim),未找到返回空字符串 */ CString GetValue(const std::vector& row, const CString& columnName) const; /** * @brief 获取字段值(按索引) * @param row 行对象 * @param columnIndex 列索引 * @return 字段值(已 Trim),越界返回空字符串 */ CString GetValue(const std::vector& row, int columnIndex) const; /** * @brief 获取字段的 double 值 * @param row 行对象 * @param columnName 列名 * @param defaultValue 默认值(字段不存在或无法转换时使用) * @return double 值 */ double GetDoubleValue(const std::vector& row, const CString& columnName, double defaultValue = 0.0) const; /** * @brief 是否为空表 */ bool IsEmpty() const { return rows.empty(); } /** * @brief 获取数据行数 */ size_t GetRowCount() const { return rows.size(); } }; public: /** * @brief 解析 TSV 数据 * @param tsvData TSV 格式的文本数据(第一行为列头,使用 Tab 分隔) * @param outTableData 输出:解析后的表格数据 * @return 是否解析成功 */ static bool Parse(const CString& tsvData, TableData& outTableData); private: /** * @brief 分割数据为行 * @param data 完整数据 * @param outLines 输出:行列表 */ static void SplitLines(const CString& data, std::vector& outLines); /** * @brief 解析单行 TSV 数据 * @param line 一行数据 * @param outFields 输出:字段列表 * @return 是否解析成功 */ static bool ParseLine(const CString& line, std::vector& outFields); /** * @brief 构建列名索引映射 * @param headers 列头列表 * @param outIndexMap 输出:列名到索引的映射 */ static void BuildColumnIndexMap(const std::vector& headers, std::map& outIndexMap); };