一、io库的基本工具
• istream(输入流)类型,提供输入操作。
• ostream(输出流)类型,提供输出操作。
• cin:读入标准输入的 istream 对象。
• cout:写到标准输出的 ostream 对象。
• cerr:输出标准错误的 ostream 对象。cerr 常用于 程序错误信息。
• >> 操作符,用于从 istream 对象中读入输入。
• << 操作符,用于把输出写到 ostream 对象中。
• getline 函数,需要分别取 istream 类型和 string 类型的两个引用形 参,其功能是从 istream 对象读取一个单词(空格分隔),然后写入 string 对象中。
二、io库的条件状态控制
参照C++Primer中的函数表
上述反应了输入输出流的条件状态
//例子1
if(cin)
//符合语法,表示可以用cin
while(cin>>n)
//合法用法,检查了流的状态,如果输入成功条件为true
//当出现系统级故障,读入无效数据或者遇到结束符eof时都会返回false
上面的例子1只能验证输入是否有效,而某些程序则需要更详细地访问或控制流的状态,此时,除了知道流处于错误状态外,还必须了解它遇到了哪种类型的错误。 这就用到了表中的类型和函数。
流的状态由 bad、fail、eof 和 good 操作提示。如果 bad、fail 或者 eof 中的任意一个为 true,则该流处于错误状态。如果这三个条件没有一个为 true,则 good 操作将返回 true。
#include<iostream>
#include<stdexcept>
using namespace std;
int main()
{
int i;
while (cin >> i, !cin.eof())//逗号操作符:首先计算它的每一个操作数,然后返回右边操作数作为整个操作的结果,cin.eof():如果到达终止符,返回true,这里表示没有到达终止符
{
if (cin.bad())
throw runtime_error("IO stream Corrupted"); //系统出现故障,输入流崩溃
if (cin.fail()) //输入类型不符合,可修正,所以continue
{
cerr << "bad data, try again" << endl;
cin.clear();//重置cin但是不清除内容
cin.sync();//清楚错误内容
//cin.clear(istream::failbit); //此处为C++primer的写法,程序会陷入死循环,原因是cin.clear(istream::failbit);就是使failbit位设置为1,而把eofbit和badbit位清除为0。
continue;
}
cout << i << endl; //输入成功,可以正确使用i
}
}
下面是函数返回和调用istream的例子
#include<iostream>
#include<stdexcept>
using namespace std;
istream& fun(istream &i)
{
int k;
while (i>>k,!i.eof())
{
if (i.bad())
{
throw runtime_error("Corrupted");
}
if (i.fail())
{
cerr << "unexpected data,try again" << endl;
i.clear();
i.sync();
continue;
}
cout << k << endl;
}
i.clear();
return i;
}
int main()
{
int k;
fun(cin);
system("pause");
}
输出缓冲区的刷新例子
cout << "zlk_flush" << flush; //直接刷新
cout << "zlk_ends" << ends; //空一格再刷新
cout << "zlk_endl" << endl; //空一行再刷新
三、iostream,fstream,sstream
1、iostream 为读写控制窗口
2、fstream为读写以命名文件
3、sstream为读写存储在内存的string对象
其类之间的派生关系为:
1、iostream:
istream类和ostream类以及iostream类不可自行创建对象,只能用iostream头文件里的全局变量cin 和cout 进行流输入和流输出。
2、fstream
文件流的使用例子:
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
int main()
{
string s;
string file_in_str;
string file_out_str;
file_in_str = "E:\\testin.txt";
string next_file = "E:\\testin2.txt";
file_out_str = "E:\\testout.txt";
//ifstream filein(file_in_str.c_str); //另外一种打开方式
//ofstream fileout(file_out_str.c_str);
ifstream filein;
ofstream fileout;
filein.open(file_in_str); //调用open方法绑定文件,当要给filein绑定新文件前要调用close()函数
fileout.open(file_out_str);
//filein.close();
if (!filein) //当open操作失败,filein为0
{
cerr << "错误:打开文件失败:" << file_in_str << endl;
}
vector<string> kk;
while (getline(filein, s)) //读输入流的一个行
//while (filein>>s) //读输入流的一个单词(遇到空格停止)
{
kk.push_back(s);
}
for (vector<string>::iterator i = kk.begin(); i < kk.end(); i++)
{
cout << *i << endl;
}
filein.close();//关闭文件
filein.clear();//刷新缓冲区
}
上例中filein.open()的文件打开还支持文件打开方式,放到第二个参数就好,下面是打开方式列表:
还有可用的组合方式:
3、sstream
sstream的基本思路可以吧fstream中绑定的文件换成字符串,然后从字符串中读取。
stringstream的基本使用:
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string s1, s2;
while (getline(cin, s1))
{
stringstream stri(s1); //给stingstream绑定一个string对象
cout << stri.str() << endl; //stri.str()为string流所有内容(一直到结束符)
while (stri >> s2) //从string流s1中读单词,读到流末尾结束
{
cout << s2 << endl;
}
}
}
该类型流主要是为了类型转化,例如,有一个数值型数据集合,要获取它们的 string 表 示形式,或反之。详情请看下面例子:
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
int a = 10, b = 24;
string s="99";
ostringstream oss;
oss.str(s); //绑定字符串s
oss << a << b; //输入到字符串的时候不会从99的结尾接着输出,而是直接修改原来的数据
string res = oss.str(); //将int型的a和b输入到字符串res中了
cout << res << endl;//输出为1024
}
用istringstream从string中读取int(float也可以)
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string a = "1001 23";
istringstream iss;
iss.str(a); //绑定字符串a
cout << istr.str() << endl;
int x, y, z;
iss >> x >> y;
z = x + y;
cout << z << endl;
}
ENDL;