【转载】C++ IO库
本篇随笔为转载,原贴地址:《C++ Primer》第8章 IO库 学习笔记。
1.IO类
#include <iostream>
istream//从流中读取数据
ostream//从流中写入数据
iostream//读写流 #include <fstream>//文件
ifstream
ofstream
fstream #include <sstream>//字符串
istringstream
ostringstream
iostringstream
fstream和sstream都继承于iostream,所以iostream有的操作他们都有。
另外流前面加字母w表示针对宽字符。
2.IO对象无拷贝和赋值
ostream o1,o2;
o1 = o2;
ostream o3(o1);
错误,不能拷贝和赋值
因为流不能拷贝和赋值,所以流作为函数参数或者是返回值必须是引用类型,且读写一个IO对象会改变其状态,
因此传递和返回的引用不能是const的
就好像
const成员函数不可改变对象内容,同时也不可通过函数返回值改变对象内容。 所以返回指向对象的指针
或引用都会被编译器拦住的。 const指针或const引用不会改变对象内容,所以可以返回。
3.IO条件状态
strm代表一种IO类型,流处于好的状态时这些bit位全部处于0。 strm::iostate iostate一种机器相关类型,提供了表达条件状态的完整功能
strm::badbit 指出流已经崩溃
strm::failbit 指出IO操作失败
strm::eofbit 指出流达到了文件的末尾
strm::goodbit 指出流处于未错误状态
s.eof() 若流处于eofbit,返回true
s.fail() 若流处于failbit,返回true
s.bad() 若流处于badbit,返回true
s.good() 若流处于有效状态,返回true
s.clear() 将流所有状态恢复,设置为有效,返回void
s.clear(flag) 将指定bit位恢复,设置为有效,返回void。flag类型为strm::iostate
s.setstate(flag) 根据给定的bit标志位,将流s中对应条件状态位置位。flag类型为strm::iostate
s.rdstate() 读取当前的状态
例子:
#include <iostream>
#include <fstream> using namespace std; istream& read(istream& is)
{
int i;
while(is >> i && i != EOF)
{
cout << i << endl;
}
cout << "eof:" << is.eof() << endl;
cout << "fail:" << is.fail() << endl;
cout << "bad:" << is.bad() << endl;
cout << "good:" << is.good() << endl;
cout << "rdstate " << is.rdstate() << endl; cout << endl; //is.clear();和下面等价
is.clear(is.rdstate() & ~is.failbit & ~is.eofbit);
//is.setstate(is.eofbit);设置了后,rdstate()结果是2 cout << "eof:" << is.eof() << endl;
cout << "fail:" << is.fail() << endl;
cout << "bad:" << is.bad() << endl;
cout << "good:" << is.good() << endl; cout << endl;
cout << "rdstate " << is.rdstate() << endl; return is;
} int main()
{
read(cin); return ;
}
结果,上面是未注释掉is.setstate(is.eofbit);的结果
下面是注释掉的结果:
还有一种可以保存流当前状态,清空,然后再恢复。
auto old_state = is.rdstate( );
is.clear( );
is.setstate(old_state);
4.管理缓冲区
#include <iostream>
using namespace std; int main()
{
cout << "hi!" << endl;
cout << "hi!" << ends; //缓冲区插入一个字符,然后刷新
cout << "hi!" << flush; //刷新缓冲区,不输出任何字符
}
5.关联输入输出缓冲区
任何试图从输入流读数据的操作都会先刷新关联的输出流。
#include <iostream>
using namespace std; int main()
{
int i;
cin >> i; //刷新cout 和 cerr;
ostream *old_str;
old_str = cin.tie(nullptr); //解开流,传递一个空指针。返回旧解
ostream &os = cout; //新建一个流
cin.tie(&os); //绑定这个新流
cin >> i;
cin.tie(old_str); //恢复以前的状态
}
6.文件的输入和输出
头文件定义了三种IO
ifstream从文件中读取数据
ofstream向一个文件写数据
fstream可以读写
//open:流用open和文件关联起来,如果open失败,failbit会被置位。因为open可能会失败,所以检查流是个好习惯
//close:当将流文件关联到另外一个文件时,必须用close关闭当前的文件。 #include <iostream>
#include <fstream>
#include <string> using namespace std; std::istream& read(std::istream& is, std::string& s) //不写引用就成为了副本
{
is >> s;
return is;
} std::ostream& print(std::ostream& os, std::string& s)//可以向iostream传递fstream,因为是派生类,不过对文件最好使用fstream
{
os << s;
return os;
} int main(int argc, char *argv[])
{
std::ifstream input(argv[]);
std::ofstream output(argv[]); std::string s;
read(input, s);
std::cout << s << std::endl;
print(output, s);
std::string ss;
//std::getline(ss, argv[1]); 读取一行
std::cin >> ss; std::string ifile = "file2";
std::ifstream in(ifile); //新建一个文件流,并且初始化,初始化意味着open()
std::ofstream out;
out.open(ifile + ".copy"); //调用open()
if(out); //如果流没错
out << ss;
out.close(); //没有close()下面error close关闭流,一个流不能重复打开多个文件
out.open("file");
if(out)
std::cout << out.good() << endl;
else
std::cerr << "error" << std::endl;
}
课后题8.5
#include <iostream>
#include <fstream>
#include <string>
#include <vector> using namespace std; int main(int argc, char *argv[])
{
string s;
fstream input(argv[]);
vector<string>ivec; while(!input.eof())//如果去掉if(input.fail())末尾会多输出一次
{
input >> s;
if(input.fail())
{
cout << "fail " << endl;
break;
}
ivec.push_back(s);
} for(string &s : ivec)
{
cout << s << endl;
}
}
没有if(input.fail( ))检查时,末尾总是会多输出一次文件末尾的内容。
看代码,文件每次读取到s中,然后push_back(s),当文件读取到最后一次时(它自己不知道读取到最后了),push_back(s)后再次读取,
发现到达末尾了,此时s中依然存着上一次的内容,push_back(s)后退出循环,所以最后一行s被push了两次,输出时当然输出两遍了。
7.文件模式
fstream fs("文件名", mode); //mode就是文件模式
in 以读的方式打开
out 以写的方式打开
app 每次写操作前均定位到末尾
ate 打开文件后立刻定位到文件末尾
trunc 截断文件
binary 以二进制方式IO
<1.只对ofstream或fstream设置out模式,out模式打开会丢弃已有数据
<2.只对ifstream或fstream设置in模式
<3.只有当out也被设定时才可以设定trunc模式
<4.只要trunc模式没被设定,就可以设定app模式,在app模式下即使没有规定out也默认为out模式
<5.没有指定trunc,以out打开也会截断文件,除非指定app,或同时打开in模式
<6.ate和binary可以用于任何类型的文件流对象,且可以和其他任何文件模式组合。
<7.每次调用open都可以指定文件模式。
8.sstream流
三个IO
istringstream
ostringstream
stringstream
特有操作
sstream strm; strm是一个未绑定的stringstream对象
sstream strm(s); strm是一个sstream对象,保存s的一个拷贝,此构造函数是explicit的
strm.str(); 返回strm所保存的string的拷贝
strm.str(s); 将string s拷贝到strm中,返回void
使用istringstream流
istringstream读字符串时遇见空格算一个字符串,就可以读一个句子的单词。
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <fstream> using namespace std; class record
{
public:
string name;
vector<string>phone;
}; int main(int argc, char *argv[])
{
ifstream input(argv[]);
string s;
vector<record>Info;
while(getline(input, s))
{
record re;
istringstream is(s);
is >> re.name;
cout << "eof" << is.eof() << endl;
while(!is.eof()) //while(is >> s)另外一种方法,不用测试eof,且注意eof成立为1
{
string s;
is >> s;
re.phone.push_back(s);
}
Info.push_back(re);
} for(record &rec : Info)
{
cout << rec.name << " ";
for(string &ph : rec.phone)
{
cout << ph << " ";
}
cout << endl;
}
}
使用ostringstream流
ostringstream流里面可以保存字符串的拷贝。需要时输出。
比如检查一个字符串是否正确,正确的保存到流里,不正确的不保存,等到结束时输出全为正确的。
string st = "asdasdasdasd";
string st1;
ostringstream os;
os << " " << st<< endl; //都写到了流里面
os << " " << st << endl;
cout << os.str() << endl; //输出字符串流里面保存的字符串,返回 字符串的拷贝
os.str(""); //使用前清空
os.str(st);
cout << os.str() << endl;
小结:
1.iostream处理控制台IO
2.fstream处理命名文件IO
3.stringstream完成内存string的IO
4.类fstream和sstream都继承自iostream,所以iostream的操作这些类也可以。
5.每个流都有一组条件状态,保证流正确无误的使用就要保证流的状态正确无误
6.为什么可以while(cin)来判断流状态,因为cin对象中重载了bool转换操作,如operator bool(),所以cin才能够参加布尔运算.
【转载】C++ IO库的更多相关文章
- [APUE]标准IO库(下)
一.标准IO的效率 对比以下四个程序的用户CPU.系统CPU与时钟时间对比 程序1:系统IO 程序2:标准IO getc版本 程序3:标准IO fgets版本 结果: [注:该表截取自APUE,上表中 ...
- [APUE]标准IO库(上)
一.流和FILE对象 系统IO都是针对文件描述符,当打开一个文件时,即返回一个文件描述符,然后用该文件描述符来进行下面的操作,而对于标准IO库,它们的操作则是围绕流(stream)进行的. 当打开一个 ...
- 文件IO函数和标准IO库的区别
摘自 http://blog.chinaunix.net/uid-26565142-id-3051729.html 1,文件IO函数,在Unix中,有如下5个:open,read,write,lsee ...
- 从Decorator,Adapter模式看Java的IO库
我想任何一本介绍模式的书在讲到Decorator模式的时候不能不提到它的实际应用--在Java/IO库里面的应用,<<Java与模式>>这本书也不例外,有点不一样的是,这本书在 ...
- C++ Primer 读书笔记: 第8章 标准IO库
第8章 标准IO库 8.1 面向对象的标准库 1. IO类型在三个独立的头文件中定义:iostream定义读写控制窗口的类型,fstream定义读写已命名文件的类型,而sstream所定义的类型则用于 ...
- 标准模板库——IO库
IO库设施: . istream(输入流)类型,提供输入操作. . ostream(输出流)类型,提供输出操作. . cin,一个istream对象,从标准输入读取数据. . cout,一个ostre ...
- 高级UNIX环境编程5 标准IO库
标准IO库都围绕流进进行的 <stdio.h><wchar.h> memccpy 一般用汇编写的 ftell/fseek/ftello/fseeko/fgetpos/fsetp ...
- IO库
IO类 C++语言不直接处理出入输出,而是通过一族定义在标准库中的类型来处理IO.这些类型支持从设备读取数据.向设备写入数据的IO操作,设备可以是文件 .控制台窗口 等.还有一些类型允许内存IO ,即 ...
- 第 8 章 IO库
第 8 章 IO库 标签: C++Primer 学习记录 IO库 第 8 章 IO库 8.1 IO类 8.2 文件输入输出 8.1 string流 8.1 IO类 IO对象无拷贝或赋值,因此不能将形参 ...
随机推荐
- 初探groupcache
groupcache是用于dl.google.com的一个memcached的替代品,相对于memcached,提供更小的功能集和更高的效率,以第三方库的形式提供服务. groupcache的常见部署 ...
- mongodb,redis,hbase 三者都是nosql数据库,他们的最大区别和不同定位是什么?
不严谨地讲,Redis定位在"快",HBase定位于"大",mongodb定位在"灵活". NoSQL的优点正好就是SQL的软肋,而其弱 ...
- springmvc学习笔记--Interceptor机制和实践
前言: Spring的AOP理念, 以及j2ee中责任链(过滤器链)的设计模式, 确实深入人心, 处处可以看到它的身影. 这次借项目空闲, 来总结一下SpringMVC的Interceptor机制, ...
- hdu4686 Arc of Dream ——构造矩阵+快速幂
link: http://acm.hdu.edu.cn/showproblem.php?pid=4686 构造出来的矩阵是这样的:根据题目的ai * bi = ……,可以发现 矩阵1 * 矩阵3 = ...
- DHCP服务器安装及配置
一.什么是DHCP? DHCP (Dynamic Host Configuration protocol)动态主机设置协议,基于UDP(发送很小的数据报文,且对时效性要求较高)协议通信. 它是C/S架 ...
- GridView 控件中如何绑定 CheckBoxList
需求:设计这样一个页面,在页面上可以选择和展示各省份对应的文明城市? 思路:一次性查询出所需的记录(查询数据库的操作不宜写到 C# 代码的循环语句中),并保存到全局变量中,之后根据条件过滤出需要的.可 ...
- 用.htaccess获取文件夹和文件名
有时需要重定向/article/1.html文件到index.php 把.htaccess放在和index.php同一个文件夹内 反向引用中的$1代表目录,$2代表去除.html后缀后的文件名 Rew ...
- locate无法open mlocate.db
# locate xxxx locate: can not open () `/var/lib/mlocate/mlocate.db': No such file or directory 如果出现此 ...
- 解决Maven项目编译时提示:源值1.5已过时,将在未来所有版本中删除
每次编译项目时,都提示:源值1.5已过时,将在未来所有版本中删除 查了一些资料,发现是因为IDEA默认把项目的源代码版本设置为jdk1.5,目标代码设置为jdk1.5 解决方案: 修改Maven的S ...
- 完成一段简单的Python程序,使用函数实现用来判断输入数是偶数还是奇数
#!/bin/usr/env python#coding=utf-8'''完成一段简单的Python程序,使用函数实现用来判断偶数和奇数'''def number_deal(a): if a%2==0 ...