软件基于VS2017 +QT5.11,用到string流,fstream流,vector等标准库,详细介绍了如何把类中的信息写入表格文件
目录
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