C++ 通过类重载操作符||结合string流与文件流把数据写入表格

软件基于VS2017 +QT5.11,用到string流,fstream流,vector等标准库,详细介绍了如何把类中的信息写入表格文件

目录

1 重载类中的输入和输出运算符

1.1 成员函数实现

1.2 友元函数实现

2 配合文件流fstream,vector把信息写入表格或者把表格信息写入到类

1 重载类中的输入和输出运算符

C++中的流插入运算符“>>”和流输出运算符“<<”在C++类库中提供的,所有的C++编译系统都会在提供输入流istream和输出流ostream,cin、cout是分别是istream类和ostream类的对象,在类库的头文件中已经对“<<”、“>>”运算符进行了重载,那么具体是怎么实现的?

因为string流有强大的模板,支持内置类型的变量,为了将类中不同数据写入文件中,我们使用strin流配合<<、>>来重载类操作符。声明方式有两种,只不过操作符重载函数的名字是“关键字"operator"以及紧跟其后的一个C++预定义的操作符”,重载方式分为成员函数和友元函数。不管那种方法string流参数都只能是引用,因为流是不可拷贝的。

1.1 成员函数实现

头文件CInfo.h

class CInfo : public QObject
{
	Q_OBJECT
public:
	CInfo(QObject *parent);
	CInfo(int id, std::string name, unsigned int age, bool sex) :nID(id), strName(name), nAge(age), bSex(sex) {};
	~CInfo();
	void operator>>(istringstream& is);
	void operator<<(ostringstream& os);
protected:
	int nID;
	std::string strName;
	unsigned int nAge;
	bool bSex;

};

源文件CInfo.cpp实现如下,其中写入ostring流时,以“,”作为分隔符,以换行符区分个数,若想写入QString,直接转换为string类型再写入string流中即可。

void CInfo::operator>>(istringstream & is)
{
	is>>  nID >> strName >>nAge >> bSex;
	return;
}

void CInfo::operator<<(ostringstream & os)
{
	os << nID << ',' << strName << ',' << nAge << ',' << bSex<<std::endl;
	return ;
}

使用的方法如下,把流中数据导入类类似。

std::ostringstream os;;//定义string输出流
CInfo *ptem=new CInfo();
(*iter) << os;//吧类信息写入string输出流,像成员函数一样使用

1.2 友元函数实现

头文件CInfo.h中类内声明如下

//友元函数声明
friend ostream& operator<<(ostream &os, CInfo &c);
friend istream& operator>>(istream &is, CInfo &c);

源文件CInfo.cpp中定义如下

注:函数返回值充当左值 需要返回一个引用

 ostream & operator<<(ostream & os, CInfo & c)
{
	 os << c.nID << ',' << c.strName << ',' << c.nAge << ',' << c.bSex << std::endl;
	 return os;
}

 istream & operator>>(istream & is, CInfo & c)
 {
	 is >> c.nID >> c.strName >> c.nAge >> c.bSex;
	 return is;
 }

使用的方法如下,把流中数据导入类类似。

std::ostringstream os;;//定义string输出流
CInfo *ptem=new CInfo();
os << *iter;;//吧类信息写入string输出流

2 配合文件流fstream,vector把信息写入表格或者把表格信息写入到类

首先我们需要一个链表来保存类的信息,以及vector<string>来把string流中数据转换到ofstream中去,类的信息存到链表使用的另一个函数,不再列出,写入文件的具体代码如下:

void COverrideIostream::saveInfo()
{
	//使用QFiledialog来获得文件路径,以csv格式
	QString fileName = QFileDialog::getSaveFileName(this, tr("Save info"), tr("*.csv"));
	std::ofstream outfile;//定义文件输出流
	std::vector<std::string> contInfo{};//使用vector来把string流中信息提取出来
	outfile.open(fileName.toStdString(), ios::out);//以输出的形式打开
	std::ostringstream os;
	if (pInfoList.isEmpty())//pInfoList为保存类的信息链表
		return;
	for (auto &iter:pInfoList)
	{
		(*iter) << os;//把类信息写入string输出流
		//os << *iter;//调用友元函数
		contInfo.push_back(os.str());//把string流中信息提取到vector
		os.str("");//对流清空,注意每次构造string流花费的时间较长,只建议构造一次
	}
	for (auto &iter:contInfo)
	{
		outfile.write(iter.c_str(), iter.size());//把vector中的每个类信息写入表格文件中
	}
	QMessageBox::warning(NULL, "提示","保存成功");
	contInfo.clear();
	outfile.close();//关闭文件流
}

导出文件类似,只不过我们需要对先前导出信息中的“,”处理一下,因为cin与cout是以空格“ ”区分变量的,string流类似。转换函数如下

void COverrideIostream::dealString(std::string & str)
{
	//处理string中的',',转换为空格
	for (auto &iter:str)
	{
		if (iter==',')
			iter = ' ';

	}
}

导入文件的过程与导出的类信息的过程相反

bool COverrideIostream::importInfo()
{
	using namespace std;
	QString strpath = QFileDialog::getOpenFileName(NULL, "导入文件", QString(), "*.csv");
	ifstream inputFile;
	istringstream is;
	string container;//作为fstream流到stringstream的转换
	inputFile.open(strpath.toStdString(), ios::in);
	getline(inputFile, container);//获取一行数据也就是一个数据
	while (!container.empty())
	{
		dealString(container);
		is.str(container);//将类中的信息写入到string流中
		CInfo *pObj = new CInfo(NULL);
		*pObj >> is;//将string流中信息写入到类中
		is.clear();//对流清空
		pInfoList.push_back(pObj);//存到链表 QList<CInfo*> pInfoList;
		getline(inputFile, container);
	}
	return false;
}

文章到此结束。

自己写的简单QT应用程序下载链接:https://download.youkuaiyun.com/download/qq_42136233/12325697

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值