C++基础第一弹:输入,输出和文件

一、第一篇

1、流和缓冲区

 C++将输入和输出看作字节流。输入时,程序从输入流中抽取字节,输出时,将字节插入到输出流中。输入流中的字节可能来自键盘,或者其他存储设备(硬盘),同样,输出流字节可以流向屏幕,打印机,存储设备或其他程序。流充当了程序和流源和流目标之间的桥梁。C++处理输入输出可以独立于来源和去向。因此管理输入和输出如下图:

  通常,使用缓冲区可以更高效的处理输入和输出。缓冲区是用作中介的内存块,它是将信息从设备传输到程序或从程序输出给设备的临时储存工具。通常,像磁盘驱动器这样的设备以512字节(或更多)的块来为单位来处理传输信息,而程序通常只能处理一个字节的信息。缓冲区可以匹配两种不同的信息传输速率。C++程序通常在用户按下回车键时刷新输入缓冲区,,对于屏幕输出,C++程序通常在用户发送换行符的时候刷新输出缓冲区。

2、流、缓冲区和iostream文件

  以下是一些类。

streambuf类为缓冲区提供了内存,用户填充缓冲区,访问缓冲区内容、刷新缓冲区和管理缓冲区内存的类方法;

ios_base类表示流的一般特征,表示是否可读取,是否是二进制还是文本流;

ios类基于ios_base,其中包括指向streambuf对象的指针成员;

ostream类是从ios类派生而来,提供输出方法;

istream类从ios类派生而来,提供输入方法;

iostream类是基于istream类和ostream类,继承了输入方法和输出方法;

例如ostream对象(如cout)处理输出,创建这样一个对象打开一个流,自动创建缓冲区,并将其与流关联起来,使得能够使用类成员函数。

C++的iostream类库管理很多细节。例如,包含iostream文件自动创建8个流对象(4个用于窄字符流,4个用于宽字符流)。

cin对象对应与标准输入流。默认关联标准输入设备(通常键盘)。wcin类似,但处理wchar_t。

cout对象对应标准输出流。默认关联标准输出设备(通常显示器)。wcout类似,处理wchar_t类型。

cerr对象与标准错误流相对应。默认关联标准输出设备(显示器)。没有被缓冲,直接发送给屏幕。wcerr类似,处理wchar_t类型。

clog对象也对应着标准错误流。默认关联输出设备,被缓冲。wclog类似,处理wchar_t类型。

标准代表流——当iostream文件为程序声明cout对象时,对象包含存储了与输出有关的信息的数据成员,如显示数据的字符宽度,小数位数,显示整数采用的计数方法,以及描述处理输出流缓冲区的streambuf对象的地址。

3、重定向

重定向能改变输入输出。

4、cout

通常结合使用cout和<<运算符。

int i=0;
cout<<i;

<<这里被称为插入运算符,插入运算符被重载,支持C++所有的基本类型。(字符型,整型,浮点型等等)

对于每一种类型,ostream类提供了operator<<()函数的定义。同时ostream类还为下面的指针类型定义了输入运算符。

const signed char*,const unsigned char*,const char*,void*

C++用指向字符串存储的位置来表示字符串。指针的形式是char数组名,显示char指针,或用引号括起来的字符串。

使用字符串的终止空字符来确定何时停止显示字符。

对于其他的指针类型,C++对应与void*,并打印地址数值表示。如果要获取字符串的地址,必须强制转换为其他类型。

1 char *s = "hello";
2 cout<<s<<endl;         //输出s字符串
3 cout<<(void*)s<<endl;  //输出s的地址

ostream & operator<<(type),type是数据类型,返回一个指向ostream&对象 的引用,其实就是返回调用运算符对象。

支持连续调用,例如cout<<"hello"<<"world"<<endl;

ostream支持put()和write()方法。前者显示字符,后者显示字符串。

ostream & put(char),同<<一样,支持拼接输出。

basic_ostream& write( const char_type* s, std::streamsize count );  //第一个参数提供要显示字符串的地址,第二个指出显示多少个字符

cout.write()返回cout对象,因为write()返回一个指向调用它的对象的引用。

write()方法不会因为遇到空字符时停止打印字符,而是打印指定数目的字符,即使超出了字符串边界

char* str = "hello";
cout.write(str,strlen(str)+1);  //会将\0显示出来,显示空白

wirte()支持数值数据,例如

long var = 566666;
cout.write((char*)&val,sizeof(long));

刷新输出缓冲区,控制符flush刷新缓冲区,控制符flush也是函数,可以直接flush(cout),也可以cout<<flush。

cout格式化,默认情况下,格式化值的方式如下:

char值,如果是可打印字符,将作为一个字符显示在宽度为一个字符的字段中。

数值型,将以10进制显示在一个刚好容纳该数字及负号(如果有)的字段中。

字符串被显示在宽度等于该字符串长度的字段中。

浮点型默认行为有变化。

新式:浮点类型显示为6位末尾0不显示。数字以定点表示法显示还是科学计数法显示,取决于值。指数大于等于6或小于等于-5时,使用科学计数法。数字宽度恰好容纳数字和负号;

老式:浮点类型显示为带6位小数,末尾0不显示。其余同上。

cout<<1.0+1.0/9;    //显示1.11111

可以通过控制符hex,oct,dec来设置显示进制,有效时间为直到将格式状态设置为其他选项为止。

支持直接调用hex()或cout<<hex;

可以通过width显示或调整宽度,注意该方法只能影响将显示的下一个项目,然后字符宽度恢复默认。

int width();//显示宽度

int width(int i);//调整宽度,并返回以前的宽度

可以通过fill()成员函数来填充字符。新的填充字符一直有效,直到更改。返回调用前填充的字符。

可以通过percision()成员函数设置精度,未采用定点计数法或者科学计数法时,设置的精度是位数,采用了定点或者科学计数法时,设置精度是小数点。新的精度一直有效,直到更改。

可以通过setf(ios_base::showpoint)显示末尾的小数点

fmtflags setf(fmtflags);//设置单个位的控制信息,并返回以前的设置

ios_base定义表示位值的常量

fmtflags setf(fmtflags,fmtflags);//第一个参数设置位常量,第二个清除第一个参数的哪些位

1 ios_base::fmtflags old = cout.setf(ios::left,ios::adjustfield);//左对齐
2 cout.setf(old,ios::adjustfield);  //恢复以前的设置

调用setf()的效果可以通过unsetf()消除

void unsetf(fmtflags mask);

cout.setf(0,ios_base::floatfield); //浮点数默认模式
cout.unsetf(ios_base::floatfield); //浮点数默认模式

可以通过cout<<left<<fixed来设置。下表列出了常见的控制符设置。

 

头文件iomanip提供了一些其他的控制符。

setprecision()设置精度

setfill()填充字符

setw()设置宽度

5、cin

cin>>value_holder;  //value_holder为存储输入的内存单元,可以是变量、引用、被解除引用的指针,也可以是类或结构成员。

istream类重载了>>运算符,可以支持(char,short,int,long,float,double的引用类型)

常见的原型如下:

istream & operator>>(int &);参数和返回值都是引用,可以修改传入的变量本身。

可以用hex,oct,dec控制符和cin一起使用,将输入为十六进制,八进制还是十进制的数据格式。

输入(unsigned,signed)char*类型时,会自动加上空值字符,使之成为字符串..

可以连续拼接使用,例如cin>>a>>b>>c;

cin检查输入时,会跳过空白(空格,换行符,制表符)直到遇见非空白字符。

流状态(iostate类型),cin或cout对象包含一个描述流状态的数据成员。

由3个ios_base元素:eofbit,badbit,failbit,其中每个元素都是一位,可以是1或者0;

当3个状态都设置为0时,说明一切顺利。

下表列出了一些报告或改变流状态的ios_base方法:

clear()清除全部的3个状态位

setstate(eofbit)设置对应的位

I/O和异常。可以采用exception()方法返回一个位字段,分别对用于,eofbit,failbit,badbit,指定异常。

get(char&)和get(void)提供不跳空白字符的单字符输入功能;

get(char*,int,char)和getline(char*,int,char)默认读取整行而不是一个单词;

第一个参数表示输入字符串的内存单元地址,第二个参数比读取的最大字符数大1,第三个是分界符,默认是换行符

如果跳过空白,采用>>;如何检查每个字符,采用get();

get()和getline()的区别:get()会将换行符或指定的分界符留在输入流中,接下来的操作先是看到换行符或分界符,getline抽取并丢弃输入流中换行符或分界符。

istream & ignore(int =1,int=EOF);默认参数值EOF导致ignore()读取指定数目的字符或读取到文件尾,支持拼接。

read()读取指定数目的字节,并将它们存储在指定的位置中,不会再输入后加空值字符,支持拼接

peek()返回输入中的下一个字符,但不会抽取输入流中字符

gcount()返回最后一个非格式化抽取方法读取的字符数。

putback()将一个字符插入到输入字符串中,被插入的字符将是下一条输入语句读取的第一个字符。

 第二篇

一、文件I/O

写文件步骤:

1、创建一个ofstream对象管理输出流;

2、将该对象与特定的文件关联起来;

3、以使用cout的方式使用该对象,唯一的区别是输出将进入文件,而不是屏幕。

头文件fstream。该文件大多数包含iostream,因此不必包含iostream。

以下是两种创建方式:

ofstream fout; //创建一个ofstream对象
fout.open("jar.txt");//关联到jar.txt文件
ofstream fout("jar.txt"); //直接创建对象并关联文件

ostream是ofstream类的基类,因此可以使用所有的ostream方法,包括插入运算符的定义,格式化方法和控制符。ofstream类使用被缓冲的输出,因此创建fout对象时,将会为缓冲区分配空间,创建多个就创建多个缓冲区。缓冲区可以大大提高程序到文件的传输数据的速度。

以这种方式创建打开文件进行输出时,没有这样的文件时,将会创建,存在则会清空,输出将进入一个空文件。

读取文件步骤:

1、创建一个ifstream对象管理输入流;

2、将该对象和特定的文件关联起来;

3、以使用cin的方式使用该对象。

创建同上。输入和输出都是被缓冲的。当输入和输出对象过期,到文件的连接自动关闭,也可以使用close()来显式关闭到文件的连接,例如fout.close();关闭这样的连接不会删除流,只是断开连接。

检查文件是否打开常见方式:

if(fin.fail())

if(fin.good())

if(!fin)

上述三种方式等价,建议使用is_open(),能够检测到试图以不合适的文件模式打开文件时的失败。

文件模式

下列是C++和C文件打开模式对比

ios_base::app只允许将数据添加到文件尾,而ios_base::ate将指针放到文件尾。

seekg用于ifstream对象,seekp用于ofstream对象

istream & seekg(streamoff,ios_base::seekdir); //定位到离第二个参数指定文件位置特定距离(字节)的位置

istream & seekg(streampos); //定位到文件离开头特定距离(字节)的位置

检查文件指针的位置,如果是输入流,tellg(),输出流tellp()方法。都是从开始处算起。

char* tmpnam(char* pszName);创建临时文件名,

2、sstream 

ostringstream类可以将信息写入其中,存储这些信息,str()方法返回一个被初始化为缓冲区内容的字符串对象

 istringstream类可以读取数据,可以使用string对象初始化

  

猜你喜欢

转载自www.cnblogs.com/mzy1314/p/10440150.html