c++中的流

streambuf类为缓冲区提供内存,并提供了用于填充缓冲区,访问缓冲区,刷新新缓冲区和管理缓冲区内存的类方法。
ios_base类表示流的一般特征,如是否可读,是二进制还是文本流等。
ios类基于ios_base,其中包括了一个之指向streambuf对象的的指针成员。
缓冲区介绍
输入:从磁盘上读取大量信息,将这些信息存储在缓冲区中,然后每次从缓冲区读取一个字节,到达缓冲区尾部,在从磁盘上读取另一块数据。
但是键盘每次输入一个字符时可以用不缓冲区,但是用缓冲区输入可以让程序没有传给程序之前返回并改正,c++通常是用户按下回车键刷新缓冲区,
输出:程序首先填满缓冲区,然后把整块数据给磁盘,并清空缓冲区,已备下一批输入。
对于输出屏幕,输出换行符时刷新缓冲区(也可能是其他:当输入语句到达时,他刷新缓冲区中当前所有输出)
刷新缓冲:用cout将字节发送给标准输出时由于ostram类对cout对象输出进行缓冲,输出并不会直接发送到目标地址,而是在缓冲区中,直到缓冲区填满,然后flush缓冲区,把内容发送出去并且清空缓冲,缓冲区通常为512byte或其整数倍。
对于屏幕来说,程序不必等到缓冲区填满,1.将换行符发送到缓冲区时刷新缓冲区;2.输入即将发生时刷新缓冲区。
由于程序运行时并不总是知道外部输入的进度,很难控制是不是全部清除输入缓冲区的内容。通常我们有可能只是希望放弃输入缓冲区中的一部分,而不是全部。比如清除掉当前行、或者清除掉行尾的换行符等等。但要是缓冲区中已经有了下一行的内容,这部分可能是我们想保留的。这个时候最好不要用sync()。可以考虑用ignore函数代替
cin.ignore(numeric_limits<std::streamsize>::max(),'/n');//清除当前行
cin.ignore(numeric_limits<std::streamsize>::max()); //清除cin里所有内容
numeric_limits<std::streamsize>::max()不过是climits头文件定义的流使用的最大值,你也可以用一个足够大的整数代替它。使用ignore显然能比sync()更精确控制缓冲区
cin.ignore(1024,'\n'),通常把第一个参数设置得足够大,这样实际上总是只有第二个参数'\n'起作用,所以这一句就是把回车(包括回车)之前的所以字符从输入缓冲(流)中清除出去。
flush(cout);
cout<<"hello word"<<flush;
cout<<"hello word"<<endl;//刷新缓冲区并插入换行符
以上三种方式均可以刷新缓冲区
但cout<<'\n';只是输出换行符,不刷新缓冲区;\n只代表换行的转义字符;\n是C中间的格式输出换行,C++保留了下来;输出'\n'是实际输出了的'\10',往输出流里添加了信息,所有的字符都是'\xx'的形式,换行符也是,你用其它任何字符输出一下,前面都会有四个'*'填充的
程序员常常在调试时添加打印语句。这类语句应该保证‘一直’刷新流。否则,如果程序崩溃,输出可能还停留在缓冲区中,从而导致关于程序崩溃位置的错误推断
缓冲区的操作https://liam.page/2017/12/31/buffer-of-stream-in-Cpp/ https://izualzhy.cn/stream-buffer
#include <iostream>
#include <sstream>
#include <cstdio>
using namespace std; int main()
{
stringstream ss;
streambuf *buf=cout.rdbuf();
//使用了新的缓冲区后,字符串不会输出到屏幕,而是由stringstream管理
cout.rdbuf(ss.rdbuf());
cout<<"hello word"<<endl; printf("%s",ss.str().c_str()); cout.rdbuf(buf);
cout<<"hello word"<<endl;
return ;
}
基于控制台

继承关系

c++将输出看做字节流,将数值类型转换为文本形式表示的字符流(将数据内部表示(二进制形式)转换为字符字节组成的输出流)
cout:对于void*类型,打印其地址数值(一端关联显示器另一端关联程序)
cin:从非空白字符开始,到与目标类型不匹配的第一个字符之间的全部内容(一端关联键盘另一端关联程序)
cerr:关联输出设备(通常为显示器)没有缓冲区,信息直接输出到屏幕,不会等到新的换行或缓冲区满
clog:关联输出设备(通常为显示器)有缓冲区
ostream:ostream &<<使用该操作符返回一个指向该对象的引用,插入操作符的返回值是调用该操作符的对象
int a=,sum=;
while(cin>>a)
sum+=a;
//输入1 2 3 4 5 6c 60
由于输入缓冲,在用户键入回车之前不会发送给程序,但是循环在了对字符c出停止了处理,导致cin>>a返回alse,终止循环
状态流
cin或cout对象包含一个描述状态流的数据成员(继承于ios_base)被定义为iostate,是bitmask类型,由eofbit,badbit,failbit,每一位可以是1(设置)0(清除)

clear:将状态设置为他的参数,默认0清楚全部状态;clear(eofbit),eofbit被设置,其他清除
setstate:setstate(eofbit)只设置eofbit,不影响其他位
get()与getline():get将换行符留在流中,getline抽取并丢弃输入流中的换行符
char tem[];
while(cin.get(tem,))//空行终止
{
//...
} //空行不终止,因为空行不导致getline设置failbit,getline抽取换行符并丢弃
while(cin.getline(tem,))
{
//...
}
//空行终止
while(cin.getline(tem,)&&tem[]!='\0')
{
//...
}
I/O异常
exceps()返回一个为字段,包含三位:eofbit,failbit,badbit。修改流状态后,clear()函数将当前流状态与exceps()的返回值比较,如果返回值中某一位被设置,当前流转态位对应位也被设置,则clear()引发ios_base::failure异常,exceptions()返回good不会引发异常,ios_base::failure从exception类派生,因此包含一个what()函数。
#include <iostream>
#include <exception>
using namespace std; int main()
{
cin.exceptions(ios_base::failbit); int a=,sum=;
try
{
while(cin>>a)
sum+=a;
}
catch(ios_base::failure &bf)
{
cout<<bf.what()<<endl;
} cout<<"last input:"<<a<<endl;
cout<<"sum:"<<sum<<endl;
return ;
}
#include <iostream>
#include <exception>
#include <fstream>
using namespace std; //filebuf in;
//istream i(&in);
int main()
{
int a=,sum=;
while(cin>>a)//只有状态流良好(所有为都被清楚)的情况下,while或if才返回true
sum+=a; cout<<"last input:"<<a<<endl;
cout<<"sum:"<<sum<<endl; if(cin.fail()&&!cin.eof())
{
cin.clear();
while(!isspace(cin.get()))//get提供不跳过空白字符读的功能
continue;
}
else
{
cout<<" i cannot go on"<<endl;
exit();
}
cout<<"now input a new number:";
cin>>a; return ;
}
cin.get(char &):到达文件末尾(真正的文件末尾,或键盘仿真文件末尾---win下ctrl+z---UNIX下ctrl+d,都不会给参数赋值,返回eof
cin.get():返回int类型的值,后不能跟抽取操作符,如:cin.get().get()>>c;
基于文件

继承关系

程序写入文件
- 创建一个ofstream对象管理输出流
- 将对象与特定的文件关联
- 用cout的方式使用该对象
- 使用colse()显示关闭文件的链接;(对象过期时(程序中止))文件的链接会自动关闭
#include <iostream>
#include <fstream>
using namespace std; int main()
{
ofstream of;
of.open("1.txt");
//ofstream of("1.txt");//也可以用构造函数 of<<"ds";
of.close();//关闭文件将刷新缓冲区,确保文件被更新
return ;
}
读取文件
- 创建一个ifstream对象管理输出流
- 将对象与特定的文件关联
- 用cin的方式使用该对象
- 使用colse()显示关闭文件的链接;(对象过期时(程序中止))文件的链接会自动关闭
#include <iostream>
#include <fstream>
using namespace std; int main()
{
ifstream fin;
fin.open("1.txt");
//ifstream fin("1.txt");//也可以用构造函数,可以用is_open()检查是否打开成功,若成功流状态为0 string s;
fin>>s;
cout<<s<<endl; fin.close();//只是断开文件的链接,对象与他的缓冲区仍然存在
return ;
}
当文件流作为类成员时,其初始化只能是初始化列表方式,即构造对象时文件,不能在构造函数体中进行操作,否则文件打开失败。
文本文件与二进制文件
文本文件:
所有内容都储存为文本,如:以文本格式存储123456,将存储6个字符,计算机内部将浮点数转为字符格式,这是<<插入操作符的工作;写文本文件时,linux,UNIX。dos c++自动将换行符转为回车和换行;读文本文件时,将本地的换行符转为c++格式;macintosh c++将换行转为回车。
二进制文件:
计算机不存储字符,而存储64位double;字符的二进制和文本表示一样(字符的ASCII二进制表示);较为精确,二进制保存数据更快,不需要转换,占用空间小,可大量存储;但二进制对于换行符,有歧义。二进制与文本文件的末未检测方式也不同。
二进制和文本模式的区别:
在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。
在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别
#include <iostream>
#include <fstream>
using namespace std; struct Stu
{
int age;
double weight;
}stu; int main()
{
ofstream of;
of.open("1.txt"); //到达stu的结构地址,并且将6个字节复制到与of相关的文件中,用write函数可以以二进制形式存储数据
of.write((char *)&stu,sizeof(stu));
of.close();//关闭文件将刷新缓冲区,确保文件被更新 //将文件中的sizeof(stu)个字节复制到结构体中
ifstream fin("1.txt");
fin.read((char *)&stu,sizeof(stu));
return ;
}
基于字符串的I/O

继承关系

#include <iostream>
#include <sstream>
using namespace std; int main()
{
ostringstream os;
string s("");
os<<s;
cout<<os.str()<<endl; ostringstream _os;
_os<<os.str();
cout<<_os.str()<<endl;//让_os从os中提取数据,str()成员函数的使用可以让istringstream对象返回一个string字符串 return ;
}
清空stringstream对象中的内容
vector<string> s(v.size(),"");//确定字符串数组的大小
stringstream ss;
for(int i=;i<v.size();++i)
{
ss<<v[i];
s[i]=ss.str();
ss.str(""); //清空stringstream对象中的内容,clear()只是清空了流的状态
}
c++中的流的更多相关文章
- [Node.js] Node.js中的流
原文地址:http://www.moye.me/2015/03/29/streaming_in_node/ 什么是流? 说到流,就涉及到一个*nix的概念:管道——在*nix中,流在Shell中被实现 ...
- 理解Java中字符流与字节流的区别
1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个“流动的方向”,通常可以从中读入一个字节序 ...
- .NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常)
.NET客户端下载SQL Server数据库中文件流保存的大电子文件方法(不会报内存溢出异常) 前段时间项目使用一次性读去SQL Server中保存的电子文件的文件流然后返回给客户端保存下载电子文件, ...
- 谈一谈Java8的函数式编程(二) --Java8中的流
流与集合 众所周知,日常开发与操作中涉及到集合的操作相当频繁,而java中对于集合的操作又是相当麻烦.这里你可能就有疑问了,我感觉平常开发的时候操作集合时不麻烦呀?那下面我们从一个例子说起. 计 ...
- Java中IO流的总结
有关Java中IO流总结图 流分类 按方向分 输入流 输出流 按单位分 字节流 字符流 按功能分 节点流 处理流(过滤流) 其他 所有的流继承与这四类流:InputSteam.OutputStream ...
- java中有关流操作的类和接口
一.java操作l流有关的类和接口 1.File 文件类 2.RandomAccessFile 随机存储文件类 3.InputStream 字节输入流 4.OutputStream 字节输出流 5.R ...
- ASP.NET Core SignalR中的流式传输
什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时 ...
- node.js中stream流中可读流和可写流的使用
node.js中的流 stream 是处理流式数据的抽象接口.node.js 提供了很多流对象,像http中的request和response,和 process.stdout 都是流的实例. 流可以 ...
- Java中IO流中的装饰设计模式(BufferReader的原理)
本文粗略的介绍下JavaIO的整体框架,重在解释BufferReader/BufferWriter的演变过程和原理(对应的设计模式) 一.JavaIO的简介 流按操作数据分为两种:字节流与字符流. 流 ...
- mongoose中的流查询stream query
mongoose中的流查询stream query,功能类似于php中的mysql_fetch_array,每次从集合中获取一条记录(文档) var cursor = Person.find({ oc ...
随机推荐
- Jon Snow and his Favourite Number CodeForces - 768C (技巧)
链接 题意 给定数组, 每次操作先将数组排序, 再将奇数位全部异或x, 求k次操作后数组最大值与最小值 (1 ≤ n ≤ 105, 0 ≤ k ≤ 105, 0 ≤ x ≤ 103) 题解 直接暴力模 ...
- A Creative Cutout CodeForces - 933D (计数)
大意:给定$n$个圆, 圆心均在原点, 第$k$个圆半径为$\sqrt{k}$ 定义一个点的美丽值为所有包含这个点的圆的编号和 定义函数$f(n)$为只有$n$个圆时所有点的贡献,求$\sum_{k= ...
- 获取Oracle数据库awr报告方法
--登录数据库 sqlplus username/passwd; --运行生成AWR报告脚本 SQL> @?/rdbms/admin/awrrpt.sql; --输入要生成报告的格式:htm ...
- linux和window是文件挂载
1. 首先在windows下面创建share文件夹并设置共享(右键->属性->共享)2. 确认ubuntu安装了mount.cifs,apt-get install mount.cifs ...
- 015PHP文件处理——文件处理flock 文件锁定 pathinfo realpath tmpfile tempname
<?php /**文件处理flock 文件锁定 pathinfo realpath tmpfile tempname */ /*$arr=pathinfo('ab.txt');//获取文件路径的 ...
- 下拉选择框 Spinner的用法。
代码如下: package com.lixu.xialakuang; import android.app.Activity; import android.content.Context; impo ...
- EhLib TitleButton SVisibleColumnsEh = '错误的列';
unit EhLibConsts; interface resourcestring SClearSelectedCellsEh = '清除选择的单元?'; SInvalidTextFormatEh ...
- Sqoop2安装
下载 http://www-us.apache.org/dist/sqoop/ 打开以上链接,开始下载sqoop2 下载后得到:sqoop-1.99.7-bin-hadoop200.tar.gz文 ...
- DevExpress v18.1新版亮点——WPF篇(一)
用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress WPF v18.1 的新功能,快来下载试用新版本!点击下载& ...
- SharePoint 2010 Ribbon with wrong style in Chrome and Safari
When we add custom ribbon to SharePoint 2010, it may display well in IE but not in Chrome and Safari ...