读写文件的几种方法std::fstream、fopen操作;解析XML方法:pugi、QDomDocument

这篇博客介绍了C++中使用std::fstream进行文件读写的操作,并探讨了XML解析的两种方法,包括使用pugi库和Qt的QDomDocument。示例代码展示了如何打开并操作文件流以及解析XML文档。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

包含头文件

#include <QtXml/QDomDocument>
#include <QtXml/QtXml>
#include <QtCore/QFile>

#include <iostream>
#include <fstream>
#include <string>
#include <vector>


typedef std::string TSString;
typedef std::vector<std::string> TSStringVec;


1.1、std::fstream读写文件

//使用fstream写文件;

void Write_FStream( const TSString &FilePath, const TSStringVec &FileVauleV )
{
	std::ofstream File;

	//ios::in	为输入(读)而打开文件;
	//ios::out	为输出(写)而打开文件;
	//ios::ate	初始位置:文件尾;
	//ios::app	所有输出附加在文件末尾;
	//ios::trunc	如果文件已存在则先删除该文件;
	//ios::binary	二进制方式;
	//ios::nocreate: 不建立文件,所以文件不存在时打开失败;
	//ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败;

	//可以用“或”把以上属性连接起来,如ios::out|ios::binary

	File.open( FilePath, std::ios::out | std::ios::app );

	if ( File.good() )
	{
		for ( size_t iFVV = 0; iFVV < FileVauleV.size(); ++iFVV )
		{
			File << FileVauleV[iFVV] << std::endl;
		}
		File.close();
	}
}

//使用fstream读文件;

TSStringVec Read_FStream( const TSString & FilePath )
{
	TSStringVec fileValueVec;

	std::ifstream File;
	File.open( FilePath, std::ios::in );
	if ( File.good() )
	{
		//成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof();
		TSString fileValue;
		while( !File.eof() )
		{
			std::getline( File, fileValue );
			fileValueVec.push_back( fileValue );
		}
	}
	return fileValueVec;
}

1.2、fopen读文件

TSString Read_FILE(const TSString & FilePath)
{
	TSString fileValue;

	FILE * fp = fopen( FilePath.c_str(), "rb" );
	//使用rb模式【二进制模式】进行读;
	//若用r模式【即 用文本方式】打开文件,会对原文件进行修改;
	//系统会将所有的"/r/n"转换成"/n";当写入文件的时候,系统会将"/n"转换成"/r/n"写入;

	if (fp)
	{
		fseek(fp, 0L, SEEK_END);
		long flen = ftell(fp);

		char * buff = new char[flen + 1];
		buff[flen] = 0;

		feek(fp, 0L, SEEK_SET);
		fread(buff, 1, flen, fp);
		fclose(fp);

		fileValue = buff;
	}

	return fileValue;
}

2.1使用pugi解析读取XML

//Ⅰ使用pugi解析XML;
{
	//关于中文的问题, clever101 曾在 pugixml库的一个使用心得 中提到,要用;
	std::locale::global( std::locale("chs") ); 
	const std::wstring strFilePath = L"D:\\Seat.xml";
	std::wifstream stream( strFilePath.c_str() );
	pugi::xml_document doc;
	doc.load(stream);
}

pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file(XMLPath.c_str(),pugi::parse_default,pugi::encoding_auto);
if ( result )
{
	//---------------------
	//<?xml version="1.0" encoding="GBK"?>
	//<root>
	//    <ip>192.168.1.1</ip>
	//</root>
	//---------------------
	//读取上述格式的ip地址;

	//这里需要注意的是,ip节点的内容是一个pcdata类型的节点;
	//这个节点的内容才是ip字符串;
	{
		pugi::xml_node node = doc.child( "root" ).child( "ip" );
		node.first_child().value();
		node.first_child().set_value( "10.10.10.10" );
	}

	//①XML_node
	{
		TSStringVec valueVec;
		pugi::xml_node node = doc.child( "Command" ).child( "OrderList" ).child( "Order" );
		for ( pugi::xml_node elementNode = node; elementNode; elementNode = node.next_sibling() )
		{
			pugi::xml_attribute attrName = elementNode.attribute( "Name" );
			TSString valueName = attrName.value();
			valueVec.push_back(valueName);
		}
	}

	//②xpath_node
	{
		TSStringVec valueVec;
		pugi::xpath_node_set node_set = doc.select_nodes( "Command/OrderList/Order" );
		for ( pugi::xpath_node_set::const_iterator iter = node_set.begin(); iter != node_set.end(); ++iter )
		{
			pugi::xml_node elementNode = iter->node();
			TSString valueName = elementNode.attribute( "Name" ).value();
			valueVec.push_back(valueName);
		}
	}

	//③解析 utg-8 格式的中文字符出现乱码;
	{
		TSString missionID, missionName;
		if ( pugi::xml_node node = doc.select_single_node( "train" ).node() )
		{
			missionID = node.attribute( "id" ).value();
		}
		if ( pugi::xml_node node = doc.select_single_node( "train" ).node() )
		{
			//自己编写的MultiByteToWideChar();
			//windows的Utf8ToWideString();

			missionName = node.attribute( "name" ).value();

			LPWSTR MNn;

			MultiByteToWideChar(CP_UTF8, 0, missionName.c_str(), CP_ACP, MNn, 0);

			TSString MN = TransCoding::Utf8ToGB2312( missionName.c_str() );

			int i = 0;
		}
	}
}

2.2 使用QDomDocument解析读取XML

//Ⅱ使用QDomDocument解析XML;
QDomDocument doc;
QFile file( XMLPath.c_str() );
if ( !file.open( QIODevice::ReadOnly ) )
{
	return;
}
if ( !doc.setContent( &file ) )
{
	file.close();
	return;
}

//读取根节点;
QDomElement train = doc.documentElement();
QString trainID = train.toElement().attribute( "id" );
QString trainName = train.toElement().attribute( "name" );

//读取第一个子节点;
QDomNode nodeSeat = train.firstChild();
if ( !nodeSeat.isNull() )
{
	QString seatID = nodeSeat.toElement().attribute("id");
	QString seatName = nodeSeat.toElement().attribute("name");

	//读取下一子节点;
	QDomElement nodeActor = nodeSeat.toElement().firstChildElement();
	QDomElement nodeSoftlist = nodeActor.firstChildElement();

	QDomNode nodeSoft = nodeSoftlist.firstChild();
	while( !nodeSoft.isNull() )
	{
		QString softName = nodeSoft.toElement().attribute("name");

		//读取下一兄弟节点;
		nodeSoft = nodeSoft.nextSibling();
	}
}

2.3使用pugi写xml

void WriteXML( TSString XMLPath , TSStringVec valueXML )
{
	//Ⅰ把.xml中文件先保存一份,然后在此基础上修改;
	{
		pugi::xml_document doc;
		pugi::xml_parse_result ret = doc.load_file( XMLPath.c_str() );
		if ( ret == pugi::status_ok )
		{
			pugi::xml_node nodeRoot = doc.child( "实体集" );
			pugi::xml_node nodeNew = nodeRoot.append_child( "实体" );
			nodeNew.append_attribute( "名称" ).set_value( "实体1" );
			nodeNew.append_attribute( "类型" ).set_value( "飞机" );
			//... ...
		}
	}

	//Ⅱ重写.XML文件;
	{
		pugi::xml_document doc;
		pugi::xml_node nodeDeclaration = doc.append_child( pugi::node_declaration );
		nodeDeclaration.set_name( "xml" );
		nodeDeclaration.append_attribute( "version" ).set_value( "1.0" );
		nodeDeclaration.append_attribute( "encoding" ).set_value( "gb2313" );

		pugi::xml_node nodeRoot = doc.append_child( "实体集" );
		pugi::xml_node nodeEntity = nodeRoot.append_child( "实体" );
		nodeEntity.append_attribute( "名称" ).set_value( "实体1" );
		nodeEntity.append_attribute( "名称" ).set_value( "实体2" );
		//... ...

		doc.save_file( XMLPath.c_str() );
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值