news 2026/2/28 15:38:29

C++:读ini文件(附带源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++:读ini文件(附带源码)

一、项目背景详细介绍

在上一节中,我们已经完成了使用 C++ 写 INI 文件的实现。但在真实的软件系统中,“写配置”只是第一步,“读配置”才是程序运行时最核心的能力

几乎所有非硬编码的程序,启动流程都会包含如下步骤:

  1. 启动程序

  2. 读取配置文件(INI / JSON / YAML 等)

  3. 解析配置参数

  4. 根据配置初始化系统

  5. 进入主业务逻辑

在轻量级应用、工具程序、跨平台项目、嵌入式系统中,INI 文件仍然是最常见、最稳定、最低依赖的配置方式之一

典型使用场景包括:

  • 服务器端口、IP、线程数配置

  • 数据库连接参数

  • 日志级别、日志路径

  • 功能开关(enable / disable)

  • 运行环境参数

因此,掌握“如何用 C++ 正确读取 INI 文件”是一项非常基础但极其重要的能力

本项目将从零开始,使用纯 C++ 标准库,实现一个完整、可扩展、工程级的 INI 文件读取示例,并系统讲解其设计与实现思路。


二、项目需求详细介绍

2.1 功能性需求

本项目需要实现以下核心功能:

  1. 打开并读取一个 INI 文件

  2. 解析文件中的Section(节)

  3. 解析每个 Section 下的Key = Value

  4. 忽略注释行与空行

  5. 将解析结果存储到内存结构中

  6. 支持通过Section + Key查询配置值


2.2 非功能性需求

为了满足教学与工程实践:

  • 仅使用 C++ 标准库

  • 代码结构清晰、注释完整

  • 易于扩展为完整配置管理模块

  • 兼容 Windows / Linux / macOS

  • 对格式有一定容错能力(空格、空行)


2.3 支持的 INI 文件格式

; 示例配置文件 [Database] host = 127.0.0.1 port = 3306 user = root password = 123456 [Server] ip = 0.0.0.0 port = 8080


三、相关技术详细介绍

3.1 INI 文件的核心元素

INI 文件由三种元素组成:

  1. 注释

    • ;#开头

  2. 节(Section)

    • [SectionName]

  3. 键值对

    • key = value


3.2 C++ 按行读取文件

使用:

std::getline(inputFile, line);

优点:

  • 自动处理不同平台换行符

  • 适合文本解析

  • 内存占用低


3.3 数据存储结构设计

为了便于查询,我们采用双层 Map 结构

Section └── Key -> Value

对应 C++ 类型:

std::map<std::string, std::map<std::string, std::string>>


3.4 字符串处理基础

解析过程中涉及:

  • 去除首尾空格

  • 判断注释行

  • 查找=位置

  • 截取字符串


四、实现思路详细介绍

整体实现流程如下:

  1. 打开 INI 文件

  2. 定义当前 Section 名称

  3. 逐行读取文件

  4. 对每一行进行预处理:

    • 去除首尾空白

    • 忽略空行和注释行

  5. 如果是 Section 行:

    • 更新当前 Section

  6. 如果是 Key=Value 行:

    • 解析 Key 和 Value

    • 存入 Map

  7. 提供接口函数获取配置值


五、完整实现代码

/******************************************************** * 文件名:read_ini.cpp * 功能:使用 C++ 读取并解析 INI 配置文件 * 说明: * 1. 支持 Section / Key / Value * 2. 忽略注释和空行 * 3. 使用 map 存储配置数据 ********************************************************/ #include <iostream> #include <fstream> #include <string> #include <map> /** * @brief 去除字符串首尾空白字符 * @param str 原始字符串 * @return 处理后的字符串 */ std::string trim(const std::string& str) { size_t first = str.find_first_not_of(" \t\r\n"); if (first == std::string::npos) { return ""; } size_t last = str.find_last_not_of(" \t\r\n"); return str.substr(first, last - first + 1); } /** * @brief INI 文件解析类 */ class IniReader { public: /** * @brief 加载并解析 INI 文件 * @param fileName INI 文件路径 * @return true 解析成功 * @return false 解析失败 */ bool load(const std::string& fileName) { std::ifstream ifs(fileName); if (!ifs.is_open()) { return false; } std::string line; std::string currentSection; // 按行读取 INI 文件 while (std::getline(ifs, line)) { // 去除首尾空白 line = trim(line); // 跳过空行 if (line.empty()) { continue; } // 跳过注释行 if (line[0] == ';' || line[0] == '#') { continue; } // Section 行 if (line.front() == '[' && line.back() == ']') { currentSection = trim(line.substr(1, line.size() - 2)); continue; } // Key=Value 行 size_t pos = line.find('='); if (pos == std::string::npos) { continue; } std::string key = trim(line.substr(0, pos)); std::string value = trim(line.substr(pos + 1)); // 存储到 map 中 data_[currentSection][key] = value; } ifs.close(); return true; } /** * @brief 获取配置值 * @param section Section 名称 * @param key Key 名称 * @param defaultValue 默认值 * @return 配置值或默认值 */ std::string get( const std::string& section, const std::string& key, const std::string& defaultValue = "") const { auto secIt = data_.find(section); if (secIt == data_.end()) { return defaultValue; } auto keyIt = secIt->second.find(key); if (keyIt == secIt->second.end()) { return defaultValue; } return keyIt->second; } private: // Section -> (Key -> Value) std::map<std::string, std::map<std::string, std::string>> data_; }; int main() { IniReader reader; if (!reader.load("config.ini")) { std::cerr << "读取 INI 文件失败!" << std::endl; return 1; } // 示例读取配置项 std::string dbHost = reader.get("Database", "host", "localhost"); std::string dbPort = reader.get("Database", "port", "3306"); std::string serverPort = reader.get("Server", "port", "8080"); std::cout << "Database Host: " << dbHost << std::endl; std::cout << "Database Port: " << dbPort << std::endl; std::cout << "Server Port: " << serverPort << std::endl; return 0; }

六、代码详细解读(仅解读方法作用)

6.1trim方法

  • 用于去除字符串首尾的空格、Tab、换行符

  • 是解析 INI 文件时的基础工具函数


6.2IniReader::load

  • 打开并逐行读取 INI 文件

  • 忽略空行和注释

  • 解析 Section 与 Key=Value

  • 将结果存储到嵌套map结构中


6.3IniReader::get

  • 根据Section + Key查询配置值

  • 如果不存在,返回默认值

  • 避免程序因缺失配置而崩溃


6.4main函数

  • 创建解析器对象

  • 加载配置文件

  • 读取并使用配置项


七、项目详细总结

通过本项目,你已经系统掌握:

  • INI 文件格式规范

  • C++ 文本文件解析流程

  • 字符串处理技巧

  • 配置数据结构设计思想

  • 可扩展配置管理的基础架构

该实现方式简单、可靠、无第三方依赖,非常适合:

  • 教学

  • 工具程序

  • 嵌入式系统

  • 基础服务组件


八、项目常见问题及解答

Q1:是否支持中文 Key / Value?

支持。INI 是纯文本格式,与编码无关。


Q2:是否支持大小写不敏感?

当前实现区分大小写,可在trim后统一转小写扩展。


Q3:是否支持同名 Key?

后出现的 Key 会覆盖前一个值


Q4:如果没有 Section 怎么办?

会存储在空字符串 Section下。


九、扩展方向与性能优化

9.1 增加getInt / getBool / getDouble

9.2 支持配置热加载(文件变更检测)

9.3 保留注释并支持原地修改

9.4 与IniWriter合并为完整配置模块

9.5 使用unordered_map提升查询性能

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/1 3:36:17

突破平台限制:MediaCrawler的5大技术突破与跨平台数据采集实践指南

突破平台限制&#xff1a;MediaCrawler的5大技术突破与跨平台数据采集实践指南 【免费下载链接】MediaCrawler-new 项目地址: https://gitcode.com/GitHub_Trending/me/MediaCrawler-new 在数据驱动决策的时代&#xff0c;如何合法合规地获取跨平台多媒体数据成为技术探…

作者头像 李华
网站建设 2026/2/28 20:48:41

MinerU适合远程办公吗?云端PDF解析服务搭建案例

MinerU适合远程办公吗&#xff1f;云端PDF解析服务搭建案例 远程办公时代&#xff0c;每天都要处理大量PDF文档&#xff1a;会议纪要、技术白皮书、合同协议、学术论文……但你有没有遇到过这些情况&#xff1f;复制粘贴文字时格式全乱、表格变成一堆空格、公式直接消失、图片…

作者头像 李华
网站建设 2026/2/27 5:57:24

3个步骤让老旧Mac重生:OpenCore Legacy Patcher全攻略

3个步骤让老旧Mac重生&#xff1a;OpenCore Legacy Patcher全攻略 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 据Apple官方数据&#xff0c;2012年前发布的Mac设备已无…

作者头像 李华
网站建设 2026/2/28 7:19:02

实测Fun-ASR-MLT-Nano:方言识别效果超乎想象

实测Fun-ASR-MLT-Nano&#xff1a;方言识别效果超乎想象 你有没有遇到过这样的场景&#xff1a;老家亲戚发来一段粤语语音&#xff0c;听不懂又不好意思问&#xff1b;客户会议录音里夹杂着浓重的四川口音&#xff0c;转文字时错漏百出&#xff1b;或者短视频里一段地道的闽南…

作者头像 李华
网站建设 2026/3/1 3:03:37

还在浪费鼠标侧键?这款开源工具让你的外设性能提升300%

还在浪费鼠标侧键&#xff1f;这款开源工具让你的外设性能提升300% 【免费下载链接】mac-mouse-fix Mac Mouse Fix - A simple way to make your mouse better. 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 当你在Excel和浏览器间频繁切换时&#…

作者头像 李华
网站建设 2026/2/28 19:24:01

被忽略的数字主权:这款工具如何让90%的追踪器失效

被忽略的数字主权&#xff1a;这款工具如何让90%的追踪器失效 【免费下载链接】brave-browser Brave browser for Android, iOS, Linux, macOS, Windows. 项目地址: https://gitcode.com/GitHub_Trending/br/brave-browser &#x1f50d; 当你的数据成为商品&#xff1a…

作者头像 李华