摘要:输出流类型,提供输出操作一个对象,从标准输入读取数据。一个对象,向标准错误写入消息。向一个给定文件写入数据。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。
istream
对象,从标准输入读取数据。ostream
对象,向标准输出写入数据。ostream
对象,向标准错误写入消息。istream
对象中读取输入数据。ostream
对象中写入输出数据。istream
对象中读取一行数据,存入到一个给定的string
对象中。iostream
头文件:从标准流中读写数据,istream
,ostream
等fstream
头文件:从文件中读写数据,ifstream
,ofstream
等sstream
头文件:从字符串中读写数据,istringstream
,ostringstream
拷贝
或赋值
由于不能拷贝IO对象,因此不能将 形参 或 返回类型 设置为 流类型。进行 IO 操作的函数通常以 引用方式 传递和 返回流。读写一个IO对象会改变其状态,因此 传递和返回的引用不能用const。
const
的。状态 | 解释 |
---|---|
strm:iostate | 是一种机器无关的类型,提供了表达条件状态的完整功能 |
strm:badbit | 用来指出流已经崩溃 |
strm:failbit | 用来指出一个IO操作失败了 |
strm:eofbit | 用来指出流到达了文件结束 |
strm:goodbit | 用来指出流未处于错误状态,此值保证为零 |
s.eof() | 若流s 的eofbit 置位,则返回true |
s.fail() | 若流s 的failbit 置位,则返回true |
s.bad() | 若流s 的badbit 置位,则返回true |
s.good() | 若流s 处于有效状态,则返回true |
s.clear() | 将流s 中所有条件状态位复位,将流的状态设置成有效,返回void |
s.clear(flags) | 将流s 中指定的条件状态位复位,返回void |
s.setstate(flags) | 根据给定的标志位,将流s 中对应的条件状态位置位,返回void |
s.rdstate() | 返回流s 的当前条件状态,返回值类型为strm::iostate |
上表中,strm
是一种IO类型,(如istream
), s
是一个流对象。
每个输出流都管理一个缓冲区,用来保存程序读写的数据。文本串可能立即打印出来,也可能被操作系统保存在缓冲区内,随后再打印。
刷新(即,数据真正写到输出设备或文件)缓冲区的IO操纵符
endl
:输出一个换行符并刷新缓冲区flush
:刷新流,但不添加任何字符ends
:在缓冲区插入空字符null
,然后刷新unitbuf
:告诉流接下来每次操作之后都要进行一次flush
操作。nounitbuf
:回到正常的缓冲方式fstream
定义了三个类型来支持文件IO: ifstream
从一个给定文件读取数据。ofstream
向一个给定文件写入数据。fstream
可以读写给定文件。操作 | 解释 |
---|---|
fstream fstrm; | 创建一个未绑定的文件流。 |
fstream fstrm(s); | 创建一个文件流,并打开名为s 的文件,s 可以是string 也可以是char 指针 |
fstream fstrm(s, mode); | 与前一个构造函数类似,但按指定mode 打开文件 |
fstrm.open(s) | 打开名为s 的文件,并和fstrm 绑定 |
fstrm.close() | 关闭和fstrm 绑定的文件 |
fstrm.is_open() | 返回一个bool 值,指出与fstrm 关联的文件是否成功打开且尚未关闭 |
上表中,fstream
是头文件fstream
中定义的一个类型,fstrm
是一个文件流对象。
文件模式 | 解释 |
---|---|
in | 以读的方式打开 |
out | 以写的方式打开 |
app | 每次写操作前均定位到文件末尾 |
ate | 打开文件后立即定位到文件末尾 |
trunc | 截断文件 |
binary | 以二进制方式进行IO操作。 |
sstream
定义了三个类型来支持内存IO: istringstream
从string
读取数据。ostringstream
向string
写入数据。stringstream
可以读写给定string
。操作 | 解释 |
---|---|
sstream strm | 定义一个未绑定的stringstream 对象 |
sstream strm(s) | 用s 初始化对象 |
strm.str() | 返回strm 所保存的string 的拷贝 |
strm.str(s) | 将s 拷贝到strm 中,返回void |
上表中sstream
是头文件sstream
中任意一个类型。s
是一个string
。
书中演示demo使用
#include #include #include #include using namespace std;typedef struct PersonInfo{ string name; vector phones;}p;int main() { string line, word; vector people; while (getline(cin, line)) { p info; istringstream record(line); record >> info.name; while (record >> word) info.phones.push_back(word); people.push_back(info); } for (auto i : people) { cout << i.name << endl; for (auto j : i.phones) cout << j << " "; cout << endl; } return 0;}
编写函数,接受一个
istream&
参数,返回值类型也是istream&
。此函数须从给定流中读取数据,直至遇到文件结束标识时停止。它将读取的数据打印在标准输出上。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。
解:
std::istream& func(std::istream &is){ std::string buf; while (is >> buf) std::cout << buf << std::endl; is.clear(); return is;}
测试函数,调用参数为
cin
。
解:
#include using std::istream;istream& func(istream &is){ std::string buf; while (is >> buf) std::cout << buf << std::endl; is.clear(); return is;}int main(){ istream& is = func(std::cin); std::cout << is.rdstate() << std::endl; return 0;}
测试
#include #include using namespace std;istream& f1(istream& is){ int s; while (is >> s) { cout << s << endl; } return is;}istream& f2(istream& is){ int s; while (is >> s) { cout << s << endl; } is.clear(); return is;}int main(){ istream& is = f1(cin); cout << is.rdstate() << endl; istream& is2 = f2(cin); cout << is2.rdstate() << endl; return 0;}
什么情况下,下面的
while
循环会终止?
while (cin >> i) /* ... */
如badbit
、failbit
、eofbit
的任一个被置位,那么检测流状态的条件会失败。
编写函数,以读模式打开一个文件,将其内容读入到一个
string
的vector
中,将每一行作为一个独立的元素存于vector
中。
#include #include #include #include using namespace std;void ReadFileToVec(const string& filename, vector& vec){ ifstream ifs(filename); if (ifs) { string buf; while (getline(ifs, buf)) vec.push_back(buf); }}
重写上面的程序,将每个单词作为一个独立的元素进行存储。
void ReadFileToVec(const string& fileName, vector& vec){ ifstream ifs(fileName); if (ifs) { string buf; while (ifs >> buf) vec.push_back(buf); }}
编写程序,将来自一个文件中的行保存在一个
vector
中。然后使用一个istringstream
从vector
读取数据元素,每次读取一个单词。
#include #include #include #include #include using namespace std;int main(){ //将来自一个文件的行保存到vector中 ifstream ifs("hello.txt"); if (!ifs) { cerr << "no data ?" << endl; return -1; } vector vecline; string line; while(getline(ifs, line)) vecline.push_back(line); ifs.close(); //从vector读取元素,每次只读一个单词 for (auto &s : vecline) { istringstream iss(s); string word; while (iss >> word) cout << word << endl; } return 0;}
本节的程序在外层
while
循环中定义了istringstream
对象。如果record
对象定义在循环之外,你需要对程序进行怎样的修改?重写程序,将record
的定义移到while
循环之外,验证你设想的修改方法是否正确。
解:
#include #include #include #include using std::vector; using std::string; using std::cin; using std::istringstream;struct PersonInfo { string name; vector phones;};int main(){ string line, word; vector people; istringstream record; while (getline(cin, line)) { PersonInfo info; record.clear(); record.str(line); record >> info.name; while (record >> word) info.phones.push_back(word); people.push_back(info); } for (auto &p : people) { std::cout << p.name << " "; for (auto &s : p.phones) std::cout << s << " "; std::cout << std::endl; } return 0;}
我们为什么没有在
PersonInfo
中使用类内初始化?
解:
因为这里只需要聚合类就够了,所以没有必要在PersionInfo
中使用类内初始化。
电话号码程序
#include #include #include #include #include using namespace std;struct PersonInfo { string name; vector phones;};bool valid(const string& str){ return isdigit(str[0]);}string format(const string& str){ return str.substr(0, 3) + "-" + str.substr(3, 3) + "-" + str.substr(6);}int main(){ //从文件中读取信息存入vector容器 ifstream ifs("phone.txt"); if (!ifs) { cerr << "no phone numbers ? " << endl; return -1; } vector people; string line, word; istringstream record; while (getline(ifs, line)) { PersonInfo info; record.clear(); record.str(line); record >> info.name; while (record >> word) { info.phones.push_back(word); } people.push_back(info); } //逐个验证电话号码 并 改变其格式 for (const auto& entry : people) //对people中的每一项 { //每个循环创建的对象 ostringstream formatted, badnums; //对每个数 for (const auto& nums : entry.phones) { if (!valid(nums)) { badnums << " " << nums; //将数的字符串形式存入badnums } else { //将格式化的字符串写入formatted formatted << " " << format(nums); } } //没有错误的数 if (badnums.str().empty()) { cout << entry.name << " " << formatted.str() << endl; } else { //打印名字和错误的数 cerr << "input error: " << entry.name << " invalid number(s)" << badnums.str() << endl; } } return 0;}
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/119673.html
摘要:二中流的概念中的流是对一种有序连续且具有方向性的数据的抽象描述。用来进行标准错误的输出。在使用时候必须要包含文件并引入标准命名空间。实际是在其底层维护了一个类型的对象用来保存结果。可以使用将让返回其底层的对象。 本文对比了C语言的输入与输出,介绍了流的概念、C++IO流以及stringst...
摘要:过滤器流,如等,是类库,是为了提供一些类让你能够处理一些极为常见的数据格式。读写器,由于流和过滤器流还是仅次于处理字节,也就是二进制。过滤器流缓冲流和类将写入的数据存储到缓冲区中一个名为的保护字节数组字段,直到缓冲区满或刷新输出流。 A little older, a little wiser, but happy to see you. ——Interstellar 2018年了,再...
摘要:通过多个装饰类实现责任链模式,它将对一个输入流的不同处理分散到不同的中去。 1、基本概念 1.1、InputStream 最基本的字节输入流,抽象类,定义了读取原始字节的所有基本方法1.1.1、public abstract int read() throws IOException 读取一个字节的方法,最基础的方法1.1.2、public int read(byte b[], in...
摘要:集合的特点集合的特点类介绍类表示了一个持久的属性集。可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串特点的子类,集合中的方法都可以用。该集合没有泛型。键值可以存储到集合中,也可以存储到持久化的设备硬盘盘光盘上。 01Properties集合的特点 * A: Properties集合的特点 * a: Properties类介绍 * Propert...
阅读 2444·2021-09-09 09:33
阅读 2818·2019-08-30 15:56
阅读 3097·2019-08-30 14:21
阅读 860·2019-08-30 13:01
阅读 814·2019-08-26 18:27
阅读 3564·2019-08-26 13:47
阅读 3431·2019-08-26 10:26
阅读 1546·2019-08-23 18:38