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

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');
}

 

相关文章:

  • CUDA 与 cuDNN 免登录下载政策详解(基于官方权威信息)
  • 软件确认测试报告:如何评估软件功能及测试关键点?
  • Java并发编程实战 Day 17:CompletableFuture高级应用
  • 爬虫+动态代理助力 AI 训练数据采集
  • QT绘制会动的蚂蚁线
  • AI服务代码说明文档
  • STM32学习之不同FLASH的芯片启动文件选择规则
  • 数据冗余对企业运营的隐性成本
  • 解决idea创建SpringBoot项目,会自动创建.git文件导致commit两极分化的现象。
  • 浅析hashmap
  • Linux驱动:framebuffer应用层实践
  • 西门子 SINAMICS S200伺服,重塑汽车焊接工艺新标准
  • 电子电路原理第十八章(有源滤波器)
  • 编程项目学习,怎么快速掌握
  • MySQL中外键约束详解 外键在表关系维护中的作用
  • 12.ack,ACK 的区别与含义
  • 从编辑到安全设置: 如何满足专业文档PDF处理需求
  • vue3 + element plus 实现表格列头、行的添加及拖动换位
  • Java NIO 面试全解析:9大核心考点与深度剖析
  • 三维自动光学检测-3D扫描扇叶尺寸检测设备-中科米堆
  • bing网站提交/深圳seo优化服务
  • 本地用织梦做网站/网络营销软件下载
  • 苏州网站制作方法/沧州网络推广外包公司
  • 北京国互网网站建设公司/网站设计与实现毕业设计
  • 有什么网站用名字做图片/百度推广是做什么的
  • 做日本外贸网站有哪些/竞价关键词优化软件