由于我们项目中经常会用到一些文本流,所以今天分享下QTextStream文本流的简单用法。
QTextStream是一个非常强大的类,它可以对IO设备,QString,QByteArray等类进行方便的读写操作。
在文本流中,QTextStream重载了两种运算符以简化输入输出流的用法,运算符<<被称为插入符,顾名思义,是往该流对象中插入数据。另一个运算符>>被称之为提取符,即从流对象中提取出数据。
请看如下代码:
#include <QTextStream> int main() { //使用提取符从标准输入中提取输入数据 QTextStream in(stdin); int i; in >> i; float f; in >> f; char buf[50]; in >> buf; //使用插入符向标准输出中写数据 QTextStream out(stdout); out << "i="; out << i; out << " f="; out << f; out << " buf="; out << buf; out << endl; } //input: 10 20.5 hello //回车 //out: i=10 f=20.5 buf=hello
当然,我们也可以将提取符和插入符连续使用:
int main() { //连续使用提取符从标准输入中提取输入数据 QTextStream in(stdin); int i; float f; char buf[50]; in >> i >> f >> buf; //连续使用插入符向标准输出中写数据 QTextStream out(stdout); out << "i=" << i << " f=" << f << " buf=" << buf << endl; } //input: 10 20.5 hello //out: i=10 f=20.5 buf=hello
但是,如果我们在输入的时候输错了,这时,文本流会如何处理呢?
int main() { //连续使用提取符从标准输入中提取输入数据 QTextStream in(stdin); int i = 10; float f = 2.5; char buf[50] = "kafka"; in >> i >> f >> buf; //连续使用插入符向标准输出中写数据 QTextStream out(stdout); out << "i=" << i << " status: " << out.status() << "\n" << "f=" << f << " status: " << out.status() << "\n" << "buf=" << buf << " status: " << out.status() << endl; } //input: hello my world //out: i=0 status: 0 // f=0 status: 0 // buf=hello status: 0
以上结果表明,输入流会跳过那些输入错误的数据,而其对应的数据类型变量会被赋值为默认值。而流的状态值也不会被修改,但是在C++标准库中,流状态会被修改。
到这里,可能有人会问,为什么输出流后面会有一个endl,其实endl的作用是刷新流,并且换行,这和标准库中的endl差不多,而且endl是属于操纵算子中的一类,关于操纵算子,小豆君在接下来的文章会专门介绍。刷新流的真正作用就是将那些存储在流内部缓冲区中的数据真正输出。
下面来做一个小实验
int main() { QTextStream in(stdin); int i; float f; char buf[50]; in >> i >> f >> buf; QTextStream out(stdout); out << "i=" << i << " f=" << f << " buf=" << buf;//去掉了endl while(true){} } //input: 10 20.5 hello //回车
当按回车时,控制台并没有打印,这是因为数据还在流的缓冲区中,并没有真正输出,所以你需要调用endl来刷新缓冲区。 如果,我们编写一个日志文件的接口,那最好就是要为我们的输出流加上endl或者flush(刷新缓冲区,但不换行),这样,即使程序崩溃,我们也能在日志文件中看到离发生错误的地方的最近的代码。
现在,我们再修改一下程序
int main() { //为out加上了作用域,当out超出作用域,调用QTextStream析构函数 { QTextStream in(stdin); int i; float f; char buf[50]; in >> i >> f >> buf; QTextStream out(stdout); out << "i=" << i << " f=" << f << " buf=" << buf;//去掉了endl } while(true){} }
当我们再次运行程序,输入数据后,程序进行了真正的输出,这是因为,在out超出作用域后,调用QTextStream析构函数,刷新缓冲区,控制台就有打印信息了。
以上代码,都使用的是标准输入输出,如果想要从文件中读取和写入,只需要向QTextStream的构造函数中传入QFile对象即可。
#include <QTextStream> #include <QFile> int main() { QFile fileIn("main.cpp");//请确保exe所在目录存在main.cpp Q_ASSERT(fileIn.open(QIODevice::ReadOnly)); QTextStream in(&fileIn); QFile fileOut("main.out"); Q_ASSERT(fileOut.open(QIODevice::WriteOnly)); QTextStream out(&fileOut); QString line; int cnt = 0; while(in.readLineInto(&line)) { out << QStringLiteral("%1: %2\n").arg(++cnt).arg(line); } }
上面的程序是将main.cpp中的文本读取出来加上行号,再写入main.out中,你是否感觉到输入输出流的强大呢,只用少许的代码,就可以将一个文件的内容复制到另一个文件,并且还可以针对文件中的内容加以修改。
好了,关于QTextStream就先介绍到这里,我们下节继续介绍它的其它强大功能。
最后也希望大家多多支持小豆君的创作,关注小豆君的公众号“小豆君Qt分享”,最新文章都会在公众号第一时间发布,或者你有不懂的问题,关注公众号后,可加好友或进Qt群获得答案。