标准输入输出

标准输入输出

标准输入输出流

  • cin 标准输入

  • cout 标准输出

  • cerr 标注错误

  • 流的四种状态

goodbit 有效状态,只有流有效时,才能正常使用
badbit  表示系统级别的错误
eofbit  表示到达了流的末尾
fialbit 表示发生了错误
bool bad() const; //若流的badbit置位,则返回true;否则返回false bool fail() const; //若流的failbit或badbit置位,则返回true;
bool eof() const; //若流的eofbit置位,则返回true;
bool good() const; //若流处于有效状态,则返回true;
extern istream cin;     /// Linked to standard input
 extern ostream cout; /// Linked to standard output
 extern ostream cerr; /// Linked to standard error (unbuffered)
 extern ostream clog; /// Linked to standard error (buffered)
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
void test0(){
int number=-1;
cout<<"cin.good():"<<cin.good()<<endl;
cout<<"cin.bad():"<<cin.bad()<<endl;
cout<<"cin.eof():"<<cin.eof()<<endl;
cout<<"cin.fail():"<<cin.fail()<<endl;
//假设从cin里面获取数据
cin>>number;//这里箭头符号的方向表示箭头的流向
cout<<"cin.good():"<<cin.good()<<endl;
cout<<"cin.bad():"<<cin.bad()<<endl;
cout<<"cin.eof():"<<cin.eof()<<endl;
cout<<"cin.fail():"<<cin.fail()<<endl;
cout<<number<<endl;
}
int main(){
test0();
return 0;
}
结果:
.jing@jing:~/code/2022-4-1$ ./stream
cin.good():1
cin.bad():0
cin.eof():0
cin.fail():0
abc    //这个地方非法输入了,导致结果出现偏差,下面会增加一个fail
cin.good():0
cin.bad():0
cin.eof():0
cin.fail():1
0

在使用流的过程中要时刻注意流的状态,防止发生流失效的情况。

  • 源码里面是用枚举表示的

 

重置流的状态

1、调用clear方法,进行重置
//clear的无参版本会复位所有错误标志位*(重置流的状态)
void clear(std::ios_base::iostate state = std::ios_base::goodbit);
2、清空缓冲区
//读取到前count个字符或在读这count个字符进程中遇到delim字符就停止,并把读取的这些东西丢掉
istream & ignore(std::streamsize count = 1, int_type delim = Traits::eof());
void test1(){
int number=-1;
//通过终端获取一个整形数据
while(cin>>number,!cin.eof())//表示没有读到流的末尾的时候
{
if(cin.bad()){
cout<<"cin had broken!"<<endl;//表示错误
return ;
}else if(cin.fail()){
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');\
               //ignore的使用
cout<<"pls input a valid integer:"<<endl;;
}else{
cout<<"number:"<<number<<endl;
}
}

缓冲区

/*
此缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。
*/

缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲。

  • 全缓冲:在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。

  • 行缓冲:在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。

  • 不带缓冲:也就是不进行缓冲,标准出错情况cerr/stderr是典型代表,这使得出错信息可以直接尽快地显示出来

//当字节数大于1024个字节时,通过cout输出的数据会立刻显示在终端上,不需要再等待三秒
void test0(){
   for(int i=0;i<1025;i++){
       cout<<'a';
  }
   sleep(3);
}

文件模式


in: 输入,文件将允许做读操作;如果文件不存在,打开失败
out: 输出,文件将允许做写操作;如果文件不存在,则直接创建一个
app: 追加,写入将始终发生在文件的末尾
ate: 末尾,读操作始终发生在文件的末尾
trunc: 截断,如果打开的文件存在,其内容将被丢弃,其大小被截断为零
binary: 二进制,读取或写入文件的数据为二进制形式
//文件输入流ifstream的使用
/*
ifstream();
explicit ifstream(const char *filename, openmode mode = in);
explicit ifstream(const string &filename, openmode mode = in);
*/
void test0(){
ifstream ifs("test.txt");//打开该文件
if(!ifs.good()){
cout<<"ifstream open file error"<<endl;
return;
}
string word;
ifs >>word;
cout<<word;

ifs.close();//关闭文件流
}
void test0(){
ifstream ifs("clog.cc");//打开该文件
if(!ifs){
cout<<"ifstream open file error"<<endl;
return;
}
//方式二:使用成员函数getline来完成
char buff[1000]={0};
while(ifs.getline(buff,1000)){
cout<<buff<<endl;
}
ifs.close();//关闭文件流
}
//读取一整个文件
void test2(){
ifstream ifs;

ifs.open("clog.cc");//第二种打开文件的方式
if(!ifs){
cout<<"ifstream open file error"<<endl;
return ;
}
//获取文件长度
int pos=ifs.tellg();//获取文件指针位置
cout<<"pos:"<<pos<<endl;

//偏移文件指针到末尾
//std::ios::cur
//std::ios::beg
//std::ios::end
ifs.seekg(0,std::ios::end);//注意第二个参数
pos=ifs.tellg();    //1、读取长短
cout<<"pos:"<<pos<<endl;
ifs.seekg(0);//回到开头 2、回到开头
char *pdata=new char [pos]();
ifs.read(pdata,pos);

string file(pdata,pos);//3、读取

cout<<file;
cout<<endl;
}
///写入一整个文件
void test1(){
std::string filename="test.txt";//当文件不存在的时候直接创造文件,如果文件存在会先清空文件中的内容,之后再进行写入
ofstream ofs(filename);
if(!ofs.good()){
cout<<"ofstream open file error"<<endl;
return ;
}
std::string line("this is a new line");
ofs<<line;
ofs.close();
}
//从后面开始写入
void test1(){
std::string filename="test.txt";//当文件不存在的时候直接创造文件
ofstream ofs(filename,std::ios::out|std::ios::app);
//app模式可以保证每一次写入文件的操作都是在文件的末尾添加数据
if(!ofs.good()){
cout<<"ofstream open file error"<<endl;
return ;
}
//输出流定位函数的名字与输入流的最后一个字母是不同的
int pos=ofs.tellp();
cout<<"pos:"<<pos<<endl;

ofs.seekp(0);
pos=ofs.tellp();
std::string line("\nhello");
ofs<<line;
ofs.close();
}

vector

扩容过程

1、申请2*capacity个元素的空间
2、将原来空间的元素copy到新空间中
3、释放原来的空间
4、最后在新空间中添加新的元素
void test0(){
vector<int> numbers(1000);//同时初始化
vector<int> numbers2;
numbers2.reserve(1000);//只开辟空间,并不存放元素
cout<<numbers.size()<<endl;//当前数组中的元素个数
cout<<numbers.capacity()<<endl;
cout<<numbers2.size()<<endl;
cout<<numbers2.capacity()<<endl;
}
//
jing@jing:~/code/2022-4-1$ ./vector
1000
1000
0
1000
void test0(){
vector<int> numbers;//同时初始化
numbers.reserve(10);
for(int idx=0;idx<10;idx++){
numbers.push_back(idx);
}
for(auto &val:numbers){
cout<<val<<" ";
}
}

字符串输入输出

void test0(){
int number=1024;
ostringstream oss;//输出流
//类比sprintf()的实现
oss<<number;
string s=oss.str();//把流中字符串的内容用s返回出来
cout<<"s: "<<s<<endl;//吧int型数据转成string型数据

}
void test1(){
std::ifstream ifs("server.conf");
if(!ifs.good()){
cout<<"ifstream open error"<<endl;
return ;
}
string line;
string key,value;
   //从上面获得信息之后,输入到iss中
while(getline(ifs,line)){
istringstream iss(line);
iss>>key>>value;
cout<<"key:"<<key<<"--->"<<"value: "<<value<<endl;
}
ifs.close();
}

 

 

 

posted @   Fancele  阅读(295)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示