0
点赞
收藏
分享

微信扫一扫

(P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流

回溯 2023-03-07 阅读 22


文章目录

  • ​​1.什么是I/O​​
  • ​​2.什么是流​​
  • ​​3.流类库继承体系​​
  • ​​4.标准输入/输出流​​

1.什么是I/O

  • 数据的输入和输出(INPUT/OUTPUT简写为I/O)
  • 3种类型的IO
    (1)标准输入输出流
    对标准输入设备和标准输出设备的输入输出简称为标准I/O
    (2)文件流
    对在外存磁盘上文件的输入输出简称为文件I/O
    (3)字符串流
    对内存中指定的字符串存储空间的输入输出简称为串I/O

2.什么是流

  • 数据输出输出的过程,可以形象地看成流
  • 从流中获取数据的操作称为“提取”(输入,>>)操作
  • 从流中添加数据的操作称为“插入”(输出,<<)操作

cin>>n    从标准输入获取变量n。从输入流到变量,称之为输入
cout<<n 向标准输出插入数据变量n。从变量到输出流,称之为输出
>>,<<箭头指向的方向代表了数据流动的方向

  • 标准IO,就有标准输入输出流
  • 文件IO,就有文件流
  • 字符串IO,就有字符串流

3.流类库继承体系

  • ios类和streambuf是平行类,大部分流类都直接或间接继承至这俩类
    ios是与输入输出相关的类;streambuf是与缓冲区相关的类
  • ios_base是ios基类,给ios类提供了流状态,输入输出格式化的功能
  • istream类继承至ios,提供流的输入操作,是输入流,重载了>>
  • ostream输出流,重载了输出的操作,重载<<
  • iostream输入输出都有
  • 字符串输入流:istringstream(>>输入操作),字符串输出流ostringstrea(<<输出操作),字符串输入输出流stringstream(>>,<<操作),
    字符串的三个流与stringbuf是组合关系,也就是这三流类包含了stringbuf成员
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ios

  • 流库具有2个平行的基类:streambuf和ios类,所有流类均以两者之一作为基类
  • streambuf类提供对缓冲区的低级操作:设置缓冲区、对缓冲区指针操作、向缓冲区存/取字符
  • ios_base,ios类记录流状态,支持对streambuf的缓冲区输入/输出的格式化或非格式化转换
  • strstreambuf:使用串保存字符序列。扩展streambuf在缓冲区提取和插入的管理
    字符串流缓冲区
  • 使用文件保存字符序列。包括打开文件:读/写、查找字符
    文件流缓冲区
  • 查看类定义
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_02

  • cin是istream类的一个对象,cout是ostream类的一个对象
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ios_03


  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_04

  • istream是basic_istream模板的一个特化,实际上真正的类应该是basic_istream<char, char_traits>;
    ostream是basic_ostream模板的一个特化
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_05


  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_06

  • basic_istream继承至basic_ios,并不是继承至ios
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_07


  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_08

  • 实际上ios是basic_ios模板的一个特化
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ios_09


  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_10

  • 清除流流状态
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_11

  • 设置流状态
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ios_12

  • 格式化操作
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_13

  • 很多格式化操作可能由ios_base提供
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_14

  • 格式化操作,科学计数法,输出宽度
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_15

  • ostream
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ios_16


  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_17

  • 插入运算符,布尔类型的输出操作
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_18

  • short类型的输出操作
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_19

  • 其他,以此类推
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ios_20


  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_21

  • eg:P58\01.cpp

#include <iostream>

using namespace std;

//实际上是2个类对象
// cout;
// cin;


int main(void)
{
int n;
cout << n <<endl;//在ostream类中重载了<<运算符,以成员函数方式重载

MyString str;
cout<<str;//不能以成员函数的方式重载的原因是:不能去更改ostream类的代码,如果每增加一个类,就去更改类重载
//的代码,这样不好。
//所以要输出自定义的类,要重载<<插入运算符,要用友元的方式重载
return 0;
}

  • 为什么将ostream和istream看成是继承ios?

    将basic_ios<_Elem, _Traits>用ios替换,把basic_istream用iostream替换。所以istream类继承至ios类。ostream类似

4.标准输入/输出流

  • C++为用户进行标准I/O操作定义了四个类对象:cin,cout,cerr和clog
    (1)cin为istream流类的对象,代表输入设备键盘,后3个为ostream流类的对象
    (2)out代表标准输出设备显示器
    (3)cerr(错误输出)和clog(位置输出)含义相同,均代表错误信息输出设备显示器
  • ostream流的操作
    (1)operator <<,插入运算符的重载
    (2)put(),输出
    (3)write(),输出
  • eg:P58\02.cpp

#include <iostream>

using namespace std;

int main(void)
{
int n = 100;
int n2 = 200;
cout <<n<<" "<<n2<<endl;
return 0;
}

  • 测试:
    为什么可以连续使用<<操作?注意:<<的返回值,<<操作返回一个ostream对象的引用,以及<<操作的重载功能(默认情况下重载了一些基本类型)
    运算符重载返回的是对象的引用,运算符重载本质上是函数重载,cout <<n函数的返回值对象的引用(cout就是ostream类型),也还是cout对象,cout对象还可以继续输出

    打断点,F9跟踪进去

    输入F11,返回的是对象的引用

    basic_ostream<_Elem, _Traits>实际上就是ostream类型
  • eg:P58\03.cpp

#include <iostream>

using namespace std;

int main(void)
{
int n = 100;
int n2 = 200;
cout <<n<<" "<<n2<<endl;

//put是ostream类的一个成员函数
//put方法的返回值也是ostream对象的引用,所以也可以连续使用
cout.put('H');
cout.put('i');
cout.put(' ');
cout.put('H').put('i').put('\n');


return 0;
}

  • 测试:
    put()操作
    输出单个字符
    返回一个ostream对象的引用
    cout.put(‘H’).put(‘i’);
    put方法的返回值也是ostream对象的引用,所以也可以连续使用
  • eg:P58\04.cpp

#include <iostream>

using namespace std;

int main(void)
{
int n = 100;
int n2 = 200;
cout <<n<<" "<<n2<<endl;

//put是ostream类的一个成员函数
//put方法的返回值也是ostream对象的引用,所以也可以连续使用
cout.put('H');
cout.put('i');
cout.put(' ');
cout.put('H').put('i').put('\n');


char buf[] = "test!!!!!";
cout.write(buf, 5);
return 0;
}

  • 测试:
    write操作
    write(buf, len)
    write()返回一个ostream对象的引用
    cout.write(buf, len)//char buf[len],输出一个缓冲区,并指定缓冲区的长度
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_22

  • istream流的操作
    (1)operator>>操作,重载了提取运算符>>
    (2)get()
    (3)getline()
    (4)read()
    (5)peek()
    (6)peek()
    (7)putback()
  • eg:P58\05.cpp

#include <iostream>

using namespace std;

int main(void)
{
int n;
char ch;

cin>>n>>ch;
cout<<"n="<<n<<" "<<"ch="<<ch<<endl;
return 0;
}

  • 测试:
    为什么可以连续使用>>操作?注意:>>的返回值,>>操作返回一个istream对象的引用,>>操作的重载功能

(P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_23

  • eg:P58\06.cpp

#include <iostream>

using namespace std;

int main(void)
{
// int n;
// char ch;

// cin>>n>>ch;
// cout<<"n="<<n<<" "<<"ch="<<ch<<endl;

int ch = cin.get();
cout<<ch<<endl;

char ch;
cin.get(ch);
cout<<ch<<endl;

char ch1;
char ch2;
cin.get(ch1).get(ch2);
cout<<ch1<<" "<<ch2<<endl;


return 0;
}

  • 测试
    get操作
    (1)读取单个字符
    (2)返回一个整数(输入的是字符,返回的是字符的ASCII码)
    (3)get对回车换行的处理
    get(char&)操作
    (1)读取单个字符
    (2)返回一个istream对象引用
    输出A的ASCII码值为65

    获取一个字符A

    get返回的是对象的引用,所以可以使用多次get
  • eg:P58\07.cpp

#include <iostream>

using namespace std;

int main(void)
{
// int n;
// char ch;

// cin>>n>>ch;
// cout<<"n="<<n<<" "<<"ch="<<ch<<endl;

// int ch = cin.get();
// cout<<ch<<endl;

// char ch;
// cin.get(ch);
// cout<<ch<<endl;

// char ch1;
// char ch2;
// cin.get(ch1).get(ch2);
// cout<<ch1<<" "<<ch2<<endl;

//getline按行获取,即使遇到空白字符,也会提取到buf中
//最多获取9个字符,还有1个是换行符
//getline不接收换行符
char buf[10] = {0};
cin.getline(buf, 10);
cout<<buf<<endl;

//提取运算符>>遇到空白字符就停止
char buf[10] = {0};
cin>>buf;
cout<<buf<<endl;

return 0;
}

  • 测试:
    getline操作,按行获取
    (1)读取一行,读取回车键
    (2)返回istream对象的引用
    (3)getline()操作与>>的区别:
    char string1[256];
    cin.getline(string1, 256);//get a whole line
    cin>>string1;//stop at the 1st blank space
  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_24


  • (P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ios_25

  • eg:P58\08.cpp

#include <iostream>

using namespace std;

int main(void)
{
// int n;
// char ch;

// cin>>n>>ch;
// cout<<"n="<<n<<" "<<"ch="<<ch<<endl;

// int ch = cin.get();
// cout<<ch<<endl;

// char ch;
// cin.get(ch);
// cout<<ch<<endl;

// char ch1;
// char ch2;
// cin.get(ch1).get(ch2);
// cout<<ch1<<" "<<ch2<<endl;

//getline按行获取,即使遇到空白字符,也会提取到buf中
//最多获取9个字符,还有1个是换行符
//getline不接收换行符
// char buf[10] = {0};
// cin.getline(buf, 10);
// cout<<buf<<endl;

// //提取运算符>>遇到空白字符就停止
// char buf[10] = {0};
// cin>>buf;
// cout<<buf<<endl;

//read对空白字符照读不误
char buf[10] = {0};
cin.read(buf, 5);
cout<<buf<<endl;

return 0;
}

  • 测试
    read(buf, len)
    返回一个istream对象的引用
    对空白字符照读不误

(P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_字符串_26


换行也会读取,a换行bcd

(P58)io流类库:什么是I/O,什么是流,流类库继承体系,标准输入/输出流_ci_27

  • eg:P58\09.cpp

#include <iostream>

using namespace std;

int main(void)
{
char c[10], c2, c3;
c2 = cin.get();
c3 = cin.get();
cin.putback(c2);//该例子来自vs,按下F11
cin.getline(&c[0], 9);
cout << c <<endl;

return 0;
}

  • 测试
    peek与putback
    peek:查看而不读取
    putback:将一个字符添加到流
    输入流中有abcdefg
    将a获取到c2变量,将b获取到c3变量,此时流中只有cdefg,然后再把c2进行putback放回流中



举报

相关推荐

0 条评论