当前位置: 首页 > ds >正文

day6补 cpp:c++输入输出流,流的四种状态,标准输入输出流

1.c++输入输出流

输入输出的含义:在编程语言中,程序的输入指从输入文件将数据传送给程序(内存),程序的输出指从程序(内存)将数据传送给输出文件

c++输入输出流机制:c++的i/o发生在流中,流是字节序列字节流从设备(如键盘,磁盘驱动器,网络连接等)流向内存,这叫做输入操作,如果字节流从内存流向设备(如显示屏,打印机,磁盘驱动器,网络连接),这叫做输出操作。程序只关心是否正确输出了字节数据和读取了字节数据

c++常用流类型

1.对系统指定的标准设备的输入和输出。即从键盘输入数据到内存,从内存输出到显示器屏幕。这种输入输出称为标准的输入输出,简称标准io

2.以外村磁盘文件为对象进行输入和输出,即从磁盘文件输入数据到内存,从内存将数据输出到磁盘文件,以外存为对象的输入输出称为文件的输入输出,简称文件io

3.对内存中指定的空间进行输入输出,通常指定一个字符数组作为存储空间(实际上可以利用该空间存储任何信息),这种输入和输出称为字符串输入输出,简称串io

注:标准io使用了通用iio,它没有自己单独的io 

2.流的四种状态 (重点)

 通过流的状态函数实现:

bool good() const   //流是goodbit状态,返回true,否则返回false

bool bad() const

bool eof() const

bool fail() const

3.标准输入输出流

标准输入流cin

  1. istream 的定义位置
    istream 是 C++ 标准输入流基类,定义在标准库头文件 <istream> 中,并直接位于 std 命名空间内。例如:

    namespace std {
      typedef basic_istream<char> istream; // 实际为basic_istream的别名
      class istream{
      public:
        void clear(..){...}
        istream& ignore(..){... return *this}
      }
      istream cin=。。。;//cin是istream类的一个实例
    }

  2. 功能与继承关系

    • istream 是输入流操作的基类,支持 >> 运算符重载,用于从数据源(如键盘、文件)读取数据。
    • 它派生出其他输入流类:
      • ifstream(文件输入流)
      • istringstream(字符串输入流)。
  3. 与 std::cin 的关系
    std::cin 是 istream 类的全局对象实例,专门处理标准输入(键盘输入)。例如:

    int x; std::cin >> x; // 调用istream::operator>>()

#include<iostream>
using std::istream;
using std::cin;
using std::cout;
using std::endl;
void printStreamStatus(istream & is){cout<<"is goodbit"<<is.good()<<endl;cout<<"is badbit"<<is.badbit()<<endl;cout<<"is failbit"<<is.failbit()<<endl;cout<<"is eofbit"<<is.eofbit()<<endl;
}
void test0(){printStreamStatus(cin); //1 0 0 0---输入流正常工作int num=10;cin>>num;cout<<"num:"<<num<<endl; printStreamStatus(cin);//若输入的是正确的数字1 0 0 0  若输入其他0 0 1 0---可恢复的错误,然后中止执行int num1=10;cin>>num1;cout<<"num1:"<<num1<<endl; printStreamStatus(cin);//若输入完正确的数字后,不按回车而是ctrl+d 0 0 0 1---跳转到流结尾
}

注意;除了goodbit状态可以连续进行下一输入,其他状态后直接退出 

cin.clear()和cin.ignore()

cin.clear()恢复流状态,cin.ignore()舍弃上次输出

如果只cin.clear() 0

void printStreamStatus(istream & is){cout<<"is goodbit"<<is.good()<<endl;cout<<"is badbit"<<is.badbit()<<endl;cout<<"is failbit"<<is.failbit()<<endl;cout<<"is eofbit"<<is.eofbit()<<endl;
}
void test0(){printStreamStatus(cin);int num=10;cin>>nnum;cout<<"num="<<num<<endl;printStreamStatus(cin);//如经过了第一次的输入,使得标准输入流进入failbit/eofbit状态//希望能够恢复流的状态if(!cin.good()){cin.clear();//恢复流的状态--1 0 0 0 //还要清空缓冲区的内容cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');//系统最大值,max()是类numeric_limits<std::streamsize>的静态成员函数}string line;cin>>line;cout<<"line="<<line<<endl;printStreamStatus(cin);}

std::numeric_limits<std::streamsize>::max()是系统最大值,max()是类numeric_limits<std::streamsize>的静态成员函数,遇到字符‘\n’之前全部释放,包括此字符'\n'都清空

若不释放全部,会导致cin.clear()恢复1 0 0 0后,下次cin不会让你输入而是直接沿用上次未用cin.ignore()清除的的输入

#include<iostream>
#include<limits>
using namespace std;
void InputInt(int &number){cout<<"请输入一个int型的数据"<<endl;cin>>number;while(!cin.eof()){if(cin.bad()){return ;}else if(cin.fail()){cin.clear();cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');cout<<"请输入一个int型的数据"<<endkl;cin>>number;}else{cout<<"num:"<<number<<endl;break;}}
}

 

输入8.9可以取8,输入89you可以取89

 

4.作业

1.

 

注意:char *str没有初始化,是野指针。

2.实现一个自定义的String类

class String {
public:String() :_pstr(new char[1]())//不要:_pstr(nullptr)因为cout对于char*有重载功能,若_pstr初始化为空指针,cout会输出中断,除非先做个if(_pstr)判断{}String(const char* pstr) :_pstr(new char[strlen(pstr)+1]()){strcpy(_pstr, pstr);}String(const String& rhs):_pstr(new char[strlen(rhs._pstr)+1]()){strcpy(_pstr, rhs._pstr);}String& operator=(const String& rhs) {if (this != &rhs) {delete[] _pstr;_pstr = new char[strlen(rhs._pstr) + 1]();strcpy(_pstr, rhs._pstr);}return *this;}~String() {if (_pstr) {delete[] _pstr;_pstr = nullptr;}}void print() {cout << _pstr << endl;}size_t length() const{//const表示不会修改成员变量size_t len = 0;char* s = _pstr;while (*_pstr != '\0') {len++;s++;}return len;}const char* c_str() const {return _pstr;}
private:char* _pstr;
};

3.创建存放Point对象的vector,并进行遍历

class Point {
public:......
private:int _x;int _y;
};
void test() {vector<Point> v{{3,0},{4,0}}vector<Point> v{3,4};//共两个,分别是Point(3,0)  Point(4,0)for (auto& ele : v) {cout << ele.print() << endl;}
}

注意:Point pt1(3,0);Point pt2(4,0);vector<Point>{pt1,pt2}

//因为Point pt1,pt2 是在栈区上创建,但vector<....>的对象必须在堆区,所以vector<Point>{pt1,pt2}中进行了拷贝构造

 

Point(1,2)调用构造函数Point(int,int)

然后将Point(1,2)调用拷贝构造函数到push_back() 

销毁栈中Point(1,2)临时对象,每个都调用一个~Point()

然后在销毁vec时要先调用析构~Point(),销毁内的每个Point元素

4.创建存放int数据的vector的vector,尝试进行遍历,并体会vector对象和元素的存储位置

5.当流失效时,如何重置流的状态,并重新再正常使用流呢?

if(!cin.good()){cin.clear();cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}

 

http://www.xdnf.cn/news/13716.html

相关文章:

  • DeepSpeed 是一个深度学习优化库,使分布式训练和推理变得简单、高效和有效
  • 黑马python(五)
  • Java项目:基于SSM框架实现的劳务外包管理系统【ssm+B/S架构+源码+数据库+毕业论文】
  • 芯片金属层M1、M2区别
  • 一站式二维码解决方案:解析其生成+解码+个性化定制的技术实现路径
  • 【Dv3Admin】系统视图用户登录API文件解析
  • 【Axure高保真原型】中继器表格更多操作
  • C#winform多选框代码
  • 现代数据工程实践:基于Dagster的ETL架构设计与实现
  • 进程信号之sigaction系统调用
  • 【技术支持】Android11 中获取应用列表
  • 商城系统源码加密与不加密(开源)的区别
  • JavaEE-Maven
  • 多线程应用
  • Project Reactor响应式编程简介
  • 初识 Redis:从入门到应用的全面指南
  • 数字化动态ID随机水印和ID跑马灯实现教育视频防录屏
  • 数据治理域——离线数据开发
  • Codeforces 2025/6/11 日志
  • 项目练习:使用mybatis的foreach标签,实现union all的拼接语句
  • Nacos快速入门:从安装到实战
  • MySQL 8.0 OCP 英文题库解析(十七)
  • 打砖块(洛谷)
  • 移动端 1px 问题解决方案
  • 从字节到对象的漂流---JavaIO流篇
  • 5. 相机拍摄简单构图
  • 1.9 Express
  • Flutter 常用组件详解:Text、Button、Image、ListView 和 GridView
  • c++中main函数执行完后还执行其它语句吗?
  • FreeRTOS互斥量