C++ 文件读写

目录

一、XML文件读写

1、写入XML文件

2、读取XML文件

二、JSON文件读写

1、写入JSON文件

2、读取JSON文件

3、写入JSON文件

4、读取JSON文件

三、CSV文件读写

1、写入CSV文件

2、读取CSV文件

四、Excel文件读写

1、写入Excel文件

2、读取Excel文件

五、INI文件读写

1、写入INI文件

2、读取INI文件


一、XML文件读写

在C++中读写XML文件,通常需要使用专门的库,因为C++标准库并没有直接提供对XML的支持。其中一个流行的库是TinyXML-2(也称为TinyXML2),它是一个简单、小巧但功能强大的XML解析器。

1、写入XML文件

cpp 复制代码
#include "tinyxml2.h"  
#include <iostream>  
#include <fstream>  
  
int main() {  
    tinyxml2::XMLDocument doc;  
    tinyxml2::XMLElement* root = doc.NewElement("Students");  
    doc.InsertFirstChild(root);  
  
    for (int i = 0; i < 3; ++i) {  
        tinyxml2::XMLElement* student = doc.NewElement("Student");  
        root->InsertEndChild(student);  
  
        tinyxml2::XMLElement* id = doc.NewElement("ID");  
        id->SetText(std::to_string(i + 1).c_str());  
        student->InsertEndChild(id);  
  
        tinyxml2::XMLElement* name = doc.NewElement("Name");  
        std::string nameStr = "Student" + std::to_string(i + 1);  
        name->SetText(nameStr.c_str());  
        student->InsertEndChild(name);  
    }  
  
    tinyxml2::XMLError eResult = doc.SaveFile("students.xml");  
    if (eResult != tinyxml2::XML_SUCCESS) {  
        std::cout << "Failed to save file\n";  
        return eResult;  
    }  
  
    std::cout << "File saved successfully\n";  
    return 0;  
}

2、读取XML文件

cpp 复制代码
#include "tinyxml2.h"  
#include <iostream>  
#include <fstream>  
  
int main() {  
    tinyxml2::XMLDocument doc;  
    tinyxml2::XMLError eResult = doc.LoadFile("students.xml");  
    if (eResult != tinyxml2::XML_SUCCESS) {  
        std::cout << "Failed to load file\n";  
        return eResult;  
    }  
  
    tinyxml2::XMLElement* root = doc.RootElement();  
    if (root == nullptr) {  
        std::cout << "Failed to get root element\n";  
        return tinyxml2::XML_ERROR_FILE_READ_ERROR;  
    }  
  
    for (tinyxml2::XMLElement* student = root->FirstChildElement("Student");  
         student != nullptr;  
         student = student->NextSiblingElement("Student")) {  
        tinyxml2::XMLElement* id = student->FirstChildElement("ID");  
        tinyxml2::XMLElement* name = student->FirstChildElement("Name")->NextSiblingElement("Name");  
  
        if (id && name) {  
            std::cout << "ID: " << id->GetText() << ", Name: " << name->GetText() << std::endl;  
        }  
    }  
  
    return 0;  
}

二、JSON文件读写

在C++中读写JSON文件,可以使用一些专门的库,如nlohmann/json(也称为json.hppjsonconsRapidJSON等)。这里我将展示如何使用nlohmann/json库来读写JSON文件。首先,你需要下载nlohmann/json的源代码并将其包含在你的项目中。

1、写入JSON文件

cpp 复制代码
#include "json.hpp"  
#include <fstream>  
#include <iostream>  
  
using json = nlohmann::json;  
  
int main() {  
    // 创建一个JSON对象  
    json j;  
    j["name"] = "John Doe";  
    j["age"] = 30;  
    j["is_student"] = false;  
    j["grades"] = {  
        {"math", 85},  
        {"english", 92},  
        {"history", 88}  
    };  
  
    // 打开文件并写入JSON数据  
    std::ofstream o("student.json");  
    o << std::setw(4) << j << std::endl; // 使用setw(4)来格式化输出,使JSON更易读  
  
    if (!o.good()) {  
        std::cerr << "Failed to write to file\n";  
        return 1;  
    }  
  
    std::cout << "File written successfully\n";  
    return 0;  
}

2、读取JSON文件

cpp 复制代码
#include "json.hpp"  
#include <fstream>  
#include <iostream>  
  
using json = nlohmann::json;  
  
int main() {  
    // 从文件读取JSON数据  
    std::ifstream i("student.json");  
    json j;  
    i >> j;  
  
    if (!i.good()) {  
        std::cerr << "Failed to read file\n";  
        return 1;  
    }  
  
    // 访问JSON数据  
    std::cout << "Name: " << j["name"] << std::endl;  
    std::cout << "Age: " << j["age"] << std::endl;  
    std::cout << "Is student: " << std::boolalpha << j["is_student"] << std::endl;  
  
    // 遍历grades数组  
    for (auto& grade : j["grades"].items()) {  
        std::cout << grade.key() << ": " << grade.value() << std::endl;  
    }  
  
    return 0;  
}

在Qt中,读写JSON文件通常使用QJsonDocumentQJsonObjectQJsonArray等类。

3、写入JSON文件

cpp 复制代码
#include <QFile>  
#include <QJsonDocument>  
#include <QJsonObject>  
#include <QJsonArray>  
#include <QDebug>  
  
int main(int argc, char *argv[]) {  
    // ... 初始化Qt应用程序等 ...  
  
    // 创建一个JSON对象  
    QJsonObject jsonObject;  
    jsonObject["name"] = "John Doe";  
    jsonObject["age"] = 30;  
    jsonObject["is_student"] = false;  
  
    // 创建一个grades数组  
    QJsonArray gradesArray;  
    gradesArray.append(QJsonObject{{"math", 85}});  
    gradesArray.append(QJsonObject{{"english", 92}});  
    gradesArray.append(QJsonObject{{"history", 88}});  
  
    // 将grades数组添加到JSON对象中  
    jsonObject["grades"] = gradesArray;  
  
    // 创建一个JSON文档并设置JSON对象为根对象  
    QJsonDocument jsonDoc(jsonObject);  
  
    // 将JSON文档写入文件  
    QFile file("student.json");  
    if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {  
        file.write(jsonDoc.toJson(QJsonDocument::Indented)); // 缩进以增加可读性  
        file.close();  
    }  
  
    // ... 清理并退出Qt应用程序 ...  
}

4、读取JSON文件

cpp 复制代码
#include <QFile>  
#include <QJsonDocument>  
#include <QJsonObject>  
#include <QJsonArray>  
#include <QDebug>  
  
int main(int argc, char *argv[]) {  
    // ... 初始化Qt应用程序等 ...  
  
    // 从文件读取JSON数据  
    QFile file("student.json");  
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {  
        QByteArray jsonData = file.readAll();  
        QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);  
  
        // 检查文档是否解析成功  
        if (!jsonDoc.isNull()) {  
            // 获取根对象  
            QJsonObject jsonObject = jsonDoc.object();  
  
            // 访问JSON数据  
            qDebug() << "Name:" << jsonObject["name"].toString();  
            qDebug() << "Age:" << jsonObject["age"].toInt();  
            qDebug() << "Is student:" << jsonObject["is_student"].toBool();  
  
            // 遍历grades数组  
            QJsonArray gradesArray = jsonObject["grades"].toArray();  
            for (const QJsonValue &gradeValue : gradesArray) {  
                QJsonObject gradeObject = gradeValue.toObject();  
                qDebug() << "Subject:" << gradeObject.keys().first()  
                         << "Grade:" << gradeObject.values().first().toInt();  
            }  
        }  
  
        file.close();  
    }  
  
    // ... 清理并退出Qt应用程序 ...  
}

三、CSV文件读写

在C++中读写CSV(Comma-Separated Values)文件通常不需要特殊的库,因为CSV文件本质上就是纯文本文件,只是数据以逗号分隔。然而,为了更方便地处理CSV文件,可以使用一些库,如csv-parserrapidcsvQt(如果你正在使用Qt框架)。

以下是一个简单的示例,展示了如何在不使用任何外部库的情况下使用C++标准库中的fstreamsstream来读写CSV文件。

1、写入CSV文件

cpp 复制代码
#include <iostream>  
#include <fstream>  
#include <vector>  
#include <string>  
  
int main() {  
    std::ofstream file("output.csv");  
  
    if (file.is_open()) {  
        std::vector<std::vector<std::string>> data = {  
            {"Name", "Age", "Country"},  
            {"John Doe", "30", "USA"},  
            {"Jane Smith", "25", "UK"}  
        };  
  
        for (const auto& row : data) {  
            for (size_t i = 0; i < row.size(); ++i) {  
                file << row[i];  
                if (i < row.size() - 1) {  
                    file << ",";  
                }  
            }  
            file << std::endl;  
        }  
  
        file.close();  
    } else {  
        std::cerr << "Unable to open file";  
    }  
  
    return 0;  
}

2、读取CSV文件

cpp 复制代码
#include <iostream>  
#include <fstream>  
#include <sstream>  
#include <vector>  
#include <string>  
  
int main() {  
    std::ifstream file("data.csv");  
    std::string line, value;  
    std::vector<std::vector<std::string>> data;  
  
    if (file.is_open()) {  
        while (std::getline(file, line)) {  
            std::istringstream iss(line);  
            std::vector<std::string> row;  
            while (std::getline(iss, value, ',')) {  
                row.push_back(value);  
            }  
            data.push_back(row);  
        }  
        file.close();  
    } else {  
        std::cerr << "Unable to open file";  
    }  
  
    // 打印数据  
    for (const auto& row : data) {  
        for (const auto& value : row) {  
            std::cout << value << " ";  
        }  
        std::cout << std::endl;  
    }  
  
    return 0;  
}

四、Excel文件读写

C++标准库并没有直接支持读写Excel文件(如.xlsx或较老的.xls格式)的功能,因为这些文件通常包含复杂的结构和元数据,远超出了CSV或纯文本文件的范畴。不过,你可以使用一些第三方库来在C++中读写Excel文件。

xlnt:这是一个C++库,用于读写Excel文件(.xlsx)。它提供了一个直观的API,可以方便地处理Excel工作簿、工作表、单元格等。

1、写入Excel文件

cpp 复制代码
#include <xlnt/xlnt.hpp>  
  
int main() {  
    // 创建一个新的工作簿  
    xlnt::workbook wb;  
  
    // 获取活动工作表  
    xlnt::worksheet ws = wb.active_sheet();  
  
    // 在单元格 A1 中写入数据  
    ws.cell("A1").value("Hello, World!");  
    ws.cell("B1").value(123);  
  
    // 保存工作簿到文件  
    wb.save("example.xlsx");  
  
    return 0;  
}

2、读取Excel文件

cpp 复制代码
#include <xlnt/xlnt.hpp>  
#include <iostream>  
  
int main() {  
    // 打开现有的工作簿  
    xlnt::workbook wb;  
    if (!wb.load("example.xlsx")) {  
        std::cerr << "Failed to open file for reading." << std::endl;  
        return 1;  
    }  
  
    // 获取活动工作表  
    xlnt::worksheet ws = wb.active_sheet();  
  
    // 读取单元格 A1 和 B1 的数据  
    std::cout << "A1: " << ws.cell("A1").to_string() << std::endl;  
    std::cout << "B1: " << ws.cell("B1").to_double() << std::endl;  
  
    return 0;  
}

五、INI文件读写

在C++中读写INI文件通常不是标准库直接支持的功能,但你可以使用第三方库或编写自己的解析器来处理INI文件格式。INI文件通常用于存储应用程序的配置信息,其格式相对简单,由节(sections)和键值对(key-value pairs)组成。

下面是一个简单的例子,展示了如何使用C++标准库函数来读写INI文件。请注意,这个例子没有处理所有可能的INI文件边缘情况,但它为基本的读写功能提供了一个出发点。

1、写入INI文件

cpp 复制代码
void writeIniFile(const std::string& filePath, const std::map<std::string, std::map<std::string, std::string>>& iniData) {  
    std::ofstream iniFile(filePath);  
  
    if (!iniFile.is_open()) {  
        std::cerr << "Failed to open INI file for writing: " << filePath << std::endl;  
        return;  
    }  
  
    for (const auto& section : iniData) {  
        iniFile << "[" << section.first << "]" << std::endl;  
        for (const auto& keyValue : section.second) {  
            iniFile << keyValue.first << " = " << keyValue.second << std::endl;  
        }  
        iniFile << std::endl; // 在每个节之后添加一个空行以提高可读性  
    }  
  
    iniFile.close();  
}

2、读取INI文件

cpp 复制代码
#include <iostream>  
#include <fstream>  
#include <sstream>  
#include <map>  
#include <string>  
  
std::map<std::string, std::map<std::string, std::string>> readIniFile(const std::string& filePath) {  
    std::map<std::string, std::map<std::string, std::string>> iniData;  
    std::ifstream iniFile(filePath);  
    std::string currentSection = "";  
  
    if (!iniFile.is_open()) {  
        std::cerr << "Failed to open INI file: " << filePath << std::endl;  
        return iniData;  
    }  
  
    std::string line;  
    while (std::getline(iniFile, line)) {  
        // 去除行首尾的空白字符  
        line = std::regex_replace(line, std::regex("^\\s+|\\s+$"), "");  
  
        // 忽略空行和注释(以分号开头的行)  
        if (line.empty() || line[0] == ';') continue;  
  
        // 检查是否是一个新的节  
        if (line[0] == '[' && line.back() == ']') {  
            currentSection = line.substr(1, line.size() - 2);  
            continue;  
        }  
  
        // 查找键值对的分隔符  
        size_t pos = line.find('=');  
        if (pos == std::string::npos) continue; // 如果没有找到分隔符,则忽略该行  
  
        std::string key = line.substr(0, pos);  
        std::string value = line.substr(pos + 1);  
  
        // 将键值对添加到当前节的map中  
        iniData[currentSection][key] = value;  
    }  
  
    iniFile.close();  
    return iniData;  
}  
  
int main() {  
    std::string filePath = "config.ini";  
    auto iniData = readIniFile(filePath);  
  
    // 打印读取到的数据  
    for (const auto& section : iniData) {  
        std::cout << "[" << section.first << "]" << std::endl;  
        for (const auto& keyValue : section.second) {  
            std::cout << keyValue.first << " = " << keyValue.second << std::endl;  
        }  
        std::cout << std::endl;  
    }  
  
    return 0;  
}
相关推荐
paidaxing_s17 分钟前
【FFMPEG基础(一)】解码源码
linux·c++·ffmpeg
曼巴UE528 分钟前
UE C++ 多镜头设置缩放 平移
开发语言·c++
悄悄敲敲敲30 分钟前
栈的实现详解
c语言·开发语言·数据结构·c++·算法·链表·线性回归
danaaaa37 分钟前
算法力扣刷题总结篇 ——【四】
数据结构·c++·算法·leetcode·职场和发展
安於宿命1 小时前
0/1背包问题总结
c语言·c++·算法·leetcode·动态规划
tutu_3211 小时前
ubuntu rc.local开机自启动
c++
森龙安3 小时前
指针 || 引用 || const || 智能指针 || 动态内存
c++
**K3 小时前
C++ 智能指针使用不当导致内存泄漏问题
开发语言·c++·算法
湫兮之风3 小时前
C++:.front()函数作用
开发语言·c++
小老鼠不吃猫3 小时前
力学笃行(四)Qt 线程与信号槽
c++·qt·信息可视化