目录
一、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.hpp
或jsoncons
、RapidJSON
等)。这里我将展示如何使用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文件通常使用QJsonDocument
、QJsonObject
、QJsonArray
等类。
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-parser
、rapidcsv
或Qt
(如果你正在使用Qt框架)。
以下是一个简单的示例,展示了如何在不使用任何外部库的情况下使用C++标准库中的fstream
和sstream
来读写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;
}