C++中不直接处理输入输出,而是通过一系列定义在标准库中的类型处理
IO,这些类型支持从设备读取数据,向设备写入数据的 IO
操作,设备可以是文件,控制台窗口等
还有一些类型允许操作内存 IO,即从 string 读取数据,向 string
写入数据
我们已经接触了
istream 输入流类型,提供输入操作。ostream
输出流类型,提供输出操作。
cin 是一个 istream 对象,从标准输入读取数据
cout 是一个 ostream 对象,向标准输出写入数据
cerr 是一个 ostream 对象,通常用于输出程序错误信息,写入到标准错误
>>运算符,用来从一个 istream 对象读取输入数据
<<运算符,用来向一个 ostream 对象写入输出数据
getline 函数,从一个给定的 istream 读取一行数据,存入一个给定的 string
对象中
先知道下面的东西大致有什么用途即可
以 w 开头的是表示支持使用宽字符的语言,C++定义类一组来操纵 wchar_t 类型的数据,宽字符版本类型和函数以 w 开头,如 wcin,wcout,wcerr
//example1.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
;
wstring name>> name;//你好
wcin << name << endl;//你好
wcout << name.length() << endl;//4
cout return 0;
}
不同的输入输出流之间只通过继承机制来实现的,所有输入流的基类都是 istream,所有输出流的基类是 ostream
总之 IO
对象是不能进行赋值的,因为不能拷贝,所以不能将形参或返回类型设置为流类型
通常会使用引用方式传递和返回,因为读写一个对象会改变其状态,传递和返回的引用不能是
const 的
流对象有自己的状态,称为操作流的条件状态
看不懂没关系,先知道有这么回事,会面的学习才会真的用起来
//example2.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
<< cin.eof() << endl;//0
cout << cin.fail() << endl;//0
cout << cin.good() << endl;//1 此时流状态位goodbit为1
cout
std::ios_base::iostate state=std::ios_base::failbit;
.setstate(state);
cin//读取条件状态
<< (cin.rdstate()==std::ios_base::failbit) << endl;//1
cout << (cin.rdstate()==cin.failbit) << endl;//1
cout << cin.good() << endl;//0
cout
return 0;
}
实际使用
//example3.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
int i;
>> i;//g
cin << cin.good() << endl;//0
cout << i << endl;//0
cout >> i;//不会被正常执行,因为cin的状态已经发生错误
cin << cin.good() << endl;//0
cout return 0;
}
如果将流操作放入 if 或者 while 等需要进行布尔检查的地方,则会检查流的状态
//example4.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
int i;
if(cin>>i){
<< i << endl;
cout }
//输入 e 输出 none
//输入 3 输出 3
return 0;
}
读取条件状态使用 rdstate()方法,使用 clear()恢复默认的状态,setstate 设置状态
//example5.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
auto old_state = cin.rdstate();
.clear();//恢复默认条件状态
cin.setstate(old_state);
cin//复位时可以保持其他标志位不变
.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
cin//辅位failbit、badbit 保持其他标志位不变
return 0;
}
每个输出流都管理一个缓冲区,用来保存程序读写的数据
<<"hello world"; os
文本可能马上打印出来,也可能保存在缓冲区中,随后打印
操作系统可以将多个程序的多个输出操作组合称单一的系统级写操作,提高效率
导致缓冲刷新,即数据真正写出输出设备或文件的原因有很多
//example6.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
<< "hello world" << endl;//输出加换行 然后刷新
cout << "hello world" << flush;//输出 然后刷新
cout << "hello world" << ends;//输出加一个空字符 然后刷新
cout //hello world
//hello worldhello world
return 0;
}
//example7.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
<< unitbuf;
cout //都cout的写入都会立即刷新缓冲区,即立即输出
//即cout不再使用缓冲区
<< "hello world";//hello world
cout << nounitbuf;//恢复使用缓冲方式
cout return 0;
}
当一个输入流关联到一个输出流时,任何试图输入流读取数据的操作都会先刷新关联的输出流,默认 cout 与 cin 关联在一起
//example8.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
<< "hello world" << endl;
cout int i;
>> i;//cout被缓冲区被刷新
cin //也就是形成了先输出才会等待输入
return 0;
}
tie()
方法允许我们进行输入和输出流之间的关联
tie
有两个重载一个接收输出流的指针(设置关联的输出流指针),一个没有参数(返回关联输出流的指针)
//example9.cpp
#include<iostream>
using namespace std;
int main(int argc,char**argv){
std::ostream* m_ostream=cin.tie();
if(m_ostream==&cout){
<< "m_ostream==&cout" << endl;//m_ostream==&cout
cout }
.tie(nullptr);//取消与其他输出流的关联
cin.tie(&cout);//恢复关联
cinreturn 0;
}
三种流对象支持对文件的内容操作,ifstream 从一个文件读取数据,ofstream 向一个给定文件写入数据,以及 fstream 可以读写给定文件
//example10.iofile
hello world
输入流的创建、文件打开与关闭
//example10.cpp
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
int main(int argc,char**argv){
//构造一个ifstream并打开给定文件
m_instream("./example10.iofile");
ifstream //或
// ifstream m_instream;
// m_instream.open("./example10.iofile");
if(m_instream.fail()||!m_instream.good()){
<< "file open failed" << endl;
cout return 0;
}
;
string strm_instream>>str;
<<str.size()<<":"<< str << endl;//5:hello
cout m_instream >> str;
<<str.size()<<":"<< str << endl;//5:world
cout m_instream >> str;
m_instream.seekg(0);//
(m_instream,str);
getline<< str.size()<<":"<<str << endl;//5:world
cout
//关闭输入流
if(m_instream.is_open()){
m_instream.close();
}
return 0;
}
对于 fstream 对象不论是栈内存对象,还是堆内存对象,当他们的离开作用域的是否,fstream 的析构函数会被调用,此时 close 会自动调用
只有当 out 被设定才能设定 trunc 模式
如果 trunc 没有被设定,可以设定 app 模式,在 app 模式即使没有显示指定
out 模式,文件总能以输出模式被打开
默认情况下,即使没有指定 trunc,以 out
模式打开的文件会被截断,为了保留以 out
模式打开的文件的内容,必须同时指定 app
模式,这样才会将数据追加到末尾或同时指定 in
ate 和 binary 模式可用于任何类型的文件流对象
默认文件模式
ifstream默认使用in模式、ofstream默认使用out模式、fstream默认使用in|out模式
//example11.cpp
#include<iostream>
#include<fstream>
using namespace std;
int main(int argc,char**argv){
m_stream;
fstream //当example11.iofile不存在时会自动创建一个空文件
m_stream.open("./example11.iofile",fstream::app|fstream::in);//追加且可写
if(m_stream.fail()){
return -1;
}
="hello world\n";
string strm_stream << str;//写到文件中去
//m_stream.write(char*,sizt_t);
m_stream.seekg(0,ios::beg);//更改读指针的位置
// m_stream.seekp(0,ios::end);//更改写指针的位置
// m_stream.tellp();
//cout << m_stream.tellg() << endl;
//m_stream.peek()!=EOF//返回文件流中的第一个字符,但并不是提取该字符。
<< m_stream.eof() << endl;//0
cout while(m_stream.good()&&!m_stream.eof()){//下一个字符不是EOF
(m_stream, str);
getline<< str<<"\n";
cout }
<< m_stream.eof() << endl;
cout m_stream.close();
return 0;
}
sstream 头文件定义了三个支持内存 IO,可以向 string 写入数据,从 string 读取数据,就像 string 是一个 IO 流一样
istringstream
从 string
读取数据,ostringstream
向 string
写入数据,而头文件stringstream
既可以从 string
读数据写可以写数据,同理这些类也继承 iostream,可以使用
iostream,istream,ostream 相关的操作
字符串输入流,即从流中读取数据
//example12.cpp
#include<iostream>
#include<sstream>
using namespace std;
int main(int argc,char**argv){
="hello world";
string strm_istringstream(str);//拷贝一份str作为输入流使用
istringstream ;
string tempm_istringstream >> temp;//从流中读取数据
<< temp << endl;//hello
cout << m_istringstream.eof() << endl;//0
cout m_istringstream >> temp;//从流中读取数据
<< temp << endl;//world
cout << m_istringstream.eof() << endl;//1
cout return 0;
}
字符串输出流,即向字符串流写数据
//example13.cpp
#include<iostream>
#include<sstream>
using namespace std;
int main(int argc,char**argv){
= "hello world";
string str m_ostringstream(str);
ostringstream m_ostringstream << " c++";
;
string temp=m_ostringstream.str();
temp<< temp << endl;//c++o world
cout m_ostringstream << "hello c++";
//返回流保存的string的拷贝
<< m_ostringstream.str() << endl;//c++hello c++
cout return 0;
}
stringstream 综合了 istringstream 与 ostringstream 的功能特性
//example14.cpp
#include<iostream>
#include<sstream>
using namespace std;
int main(int argc,char**argv){
;
stringstream stream<< "hello world";//向流写入内容
stream
<< stream.str() << endl;//hello world
cout
;
string temp>> temp;//从流中读取内容
stream
<< stream.eof() << endl;//0
cout << temp << endl;//hello
cout
>> temp;//从流中读取内容
stream
<< temp << endl;//world
cout << stream.eof() << endl;//1
cout return 0;
}
不要慌,在此学习的内容不是文件操作,如果从 C 语言来学 C++我们的思想要逐渐学习面向对象的思想,C++向我们提供了强大的 IO 流的操作的封装,这使得开发更加便捷,使用得当代码也能得到较好的维护性