C++读取文件跳过注释存入map<string,string>的实现问题求解
现有代码问题
- 注释过滤逻辑错误:原代码没有在读取整行后第一时间过滤注释、空行,而是在逐词拆分阶段判断,既无法处理行首带空白的注释行,还会产生无效的拆分逻辑。
- 键值拆分逻辑不符合需求:需求规则是每行第一个单词为map的键,该行剩余全部内容(保留原始多字段、空格格式)为对应的值。原代码循环按“两个单词一组”的规则拆分插入,会把包含多个字段的行拆成多个错误键值对,比如
Mango fruit 5 50会被错误拆为Mango->fruit、5->50两个条目,表头行也会被拆成两组无效键值。 - 输出格式不匹配:原代码用固定空格分隔键值,没有使用预期的
->分隔符。
额外说明:
std::map是按键字典序排序的有序容器,遍历输出时的顺序和文件原始行顺序不一致。如果需要严格保留文件行的先后顺序,可以将存储结构替换为std::vector<std::pair<std::string, std::string>>,或使用支持插入序的映射结构。
修改后可运行代码
#include <map> #include <string> #include <fstream> #include <sstream> #include <iostream> using namespace std; void check(ifstream &inputFile, map<string, string> &diffm) { diffm.clear(); string line; while (getline(inputFile, line)) { // 过滤空行 size_t content_start = line.find_first_not_of(" \t"); if (content_start == string::npos) continue; // 过滤注释行 if (line[content_start] == '#') continue; stringstream ss(line); string key, value; // 读取行首第一个单词作为键 ss >> key; // 跳过键后面的连续空白 ss >> ws; // 读取剩余所有内容作为值,保留原始空格格式 getline(ss, value); diffm[key] = value; } } int main(int argc, char const *argv[]) { map<string, string> list1; if (argc >= 2) { ifstream inputFile(argv[1]); if (!inputFile.is_open()) { cerr << "Failed to open input file\n"; return -1; } check(inputFile, list1); for (auto itr = list1.begin(); itr != list1.end(); itr++) { cout << itr->first << " -> " << itr->second << "\n"; } } else { cerr << "Usage: <prog name> <input file path>\n"; return -2; } return 0; }
逻辑说明
- 读取每一行后先判断是否为空行、注释行,符合条件直接跳过,不进入后续拆分逻辑,注释判定规则为行首(跳过前导空格、制表符后)第一个字符为
#,符合通用配置文件的注释规范。 - 拆分键值时,仅读取第一个单词作为键,剩余行内容全部作为值存入,完全匹配预期的存储格式,不会把多字段的行拆成多个无效键值对。
- 增加了文件打开失败的异常判断,避免空文件流导致的无提示运行错误。
- 输出格式调整为和预期一致的
->分隔样式。
内容的提问来源于stack exchange,提问作者Amith Kotian
相关产品推荐
相关产品推荐

