第十一章 输入 /输出流本章主要内容
1,C++中的输入 /输出概述 -- 概念 理解
2,C++中的流类库和流对象 -- 了解
3,格式化输入 /输出 -- 掌握
4,流操作错误的检测 -- 掌握
5,用流对象进行文件操作 -- 重点 熟练掌握
16:38:22
§ 1 C++的输入 /输出概述
C++支持两种方式的输入 /输出
兼容 C语言的方式调用 C语言的 scanf(),printf()等库函数
使用流对象的方式
C++中把数据从一个对象向另外一个对象的流动抽象成 流
流对象一般与一个文件相关联,使用流对象进行输入相当于从文件中读取数据存放于变量或对象中;使用流对象进行输出,相当于把要输出的数据写入文件中
流好比管道,从一端放进什么数据,从另一端就能取出什么数据
流提供了统一的输入 /输出操作,<< 和 >>
使用流对象进行输入时,从流对象中取出数据的操作称为 提取操作,格式为,流对象 >> 变量;
使用流对象进行输出时,把数据添加进流对象中的操作称为 插入操作,格式为,流对象 << 数据 ;
16:38:22
插入运算符与提取运算符可以分别串联使用例,cin >> a >> b >> c >> d;
cout << a <<?A? << 2.5 <<,abcde” << endl;
使用 >>输入时,用户从键盘输入的多个数据项之间可以用空格,Tab或回车分隔
<< 和 >>具有智能,能够自动判断其后数据项的类型,并采用相应的类型进行输出或输入
cin和 cout是系统预定义的流对象,分别与键盘和显示器相关联
C++中的流既提供了低级的 I/O功能,也提供了高级的 I/O
功能
低级 I/O把一切数据看做是无格式的字节序列 (字节流 ),
对字节序列不做解释,可用于实现高速大容量的数据传输
高级 I/O不把数据看做是字节流,而 把字节序列解释为各种预定义的或用户自定义的类型的数据,有一定格式
16:38:22
§ 2 流类库与流对象
C++的流类库是用继承机制建立起来的一个输入 /输出类库
主要有两个平行的基类,streambuf 和 ios
它们是所有流类的基类
streambuf
filebuf strstreambuf stdiobuf
streambuf类主要负责缓冲区的管理,提供对缓冲区的低级操作,如设置缓冲区大小,从缓冲区中提取字节,把字节插入缓冲区等
filebuf类提供文件缓冲区的管理
strstreambuf的对象使用字符串保存字符序列,提供在内存中提取和插入数据的缓冲区管理
stdiobuf提供标准 I/O文件的缓冲区管理
16:38:22
ios是抽象基类,提供输入 /输出所需的公共操作 。 类中包含一指向 streambuf类对象的指针,并提供进行格式化 I/O和设置文件模式所需的枚举常量,和对 I/O错误的处理操作
istream类提供了大部分输入操作,并重载了 >> 运算符
ios
istream ostream
ifstream istream_withassign istrstream ofstream ostream_withassign ostrstream
iostream
fstream strstream stdiostream
ifstream文件输入流类,其对象与一个文件关联,用于从该文件中输入数据
istrstream字符串输入流类,用于从其对象中提取数据
istream_withassign:预定义对象 cin所属的流类,重载了赋值运算符 =
16:38:22
ostream类及其派生类提供流的各种格式化,非格式化输出操作,对所有系统预定义的输出流重载插入运算符 <<
ofstream文件输出流类,其对象与一个文件关联,用于向该文件中插入数据
ostrstream字符串输出流类,用于把数据插入到一个该类对象,由该类对象在内存中形成一个字符串
ostream_withassign类:系统预定义的流对象 cout所属的类,重载了赋值运算符 =
16:38:22
C++推荐使用流对象的方式进行输入 /输出操作,且提供了
4个预定义的流对象,分别是,cin,cout,cerr 和 clog
cin:是 istream_withassign类的对象,标准输入流对象,
通常与标准输入设备 (键盘 )关联,可以被重定向
cout:是 ostream_withassign类的对象,标准输出流对象,
通常与标准输出设备 (显示器 )关联,可以被重定向
cerr:是 ostream_withassign类的对象,标准错误输出流对象,使用语法与 cout相似,但与监视器关联,内部无缓冲区,不能被重定向
clog:是 ostream_withassign类的对象,标准错误输出流对象,使用语法与 cout相似,与监视器关联,内部有缓冲区,不能被重定向使用流类库和流对象时,必须要包含相应的头文件,并使用命令 using namespace std;打开 std名称空间
16:38:22
§ 3 格式化输入 /输出
C++中的流支持两种方式的输入 /输出格式控制
1.使用 ios类的成员函数 2.使用操纵符
使用 ios类的成员函数进行输入 /输出格式控制
1.格式控制标志字
ios类中定义了一个成员变量,用于记录当前流的格式化状态,该成员变量称为 格式控制标志字
为了方便记忆,ios类中定义了一些格式控制枚举常量,
每个常量对应于一种输入 /输出格式
16:38:22
格式控制枚举常量标志常量 值 意义 I/O
ios::skipws 0x0001 跳过输入的空白 I
ios::left 0x0002 左对齐输出 O
ios:right 0x0004 右对齐输出 O
ios:internal 0x0008 在符号位或基指示符之后填充 O
ios::dec 0x0010 十进制格式输入 /输出 I/O
ios::oct 0x0020 八进制格式输入 /输出 I/O
ios::hex 0x0040 十六进制格式输入 /输出 I/O
ios::showbase 0x0080 输出中显示基指示符 O
ios::showpoint 0x0100 输出时显示小数点 O
ios::uppercase 0x0200 十六进制输出时用大写字母显示 O
ios::showpos 0x0400 输出正数时显示,+” O
ios::scientific 0x0800 输出时以科学计数法显示浮点数 O
ios::fixed 0x1000 定点形式显示浮点数 O
ios::unitbuf 0x2000 插入操作后立即刷新流 O
ios::stdio 0x4000 插入操作后刷新流 stdio和 stderr O
16:38:22
2.ios类中控制输入 /输出格式的成员函数
设置和返回标志字
long flags(long lFlags):用参数 lFlags的值更新标志字,
返回更新前的标志字
long flags()const:返回标志字的值
设置标志字中的某些位
log setf(long lFlags):设置参数 lFlags指定的标志位,
返回更新前的标志字的值
long setf(long lFlags,long lMasks):将参数 lMasks指定的标志位清 0,并设置参数 lFlags指定的标志位,返回更新产的标志字的值
清除标志字
long unsetf(long lFlags):将参数 lFlags指定的标志位清 0,返回更新前的标志字的值
16:38:22
设置和返回输出宽度
int width(int nw):设置输出项的显示宽度为 nw
int width()const:返回当前的输出宽度值
设置填充字符
char fill(char cFill):当设置宽度大于数据显示所需宽度时,空白位置以字符 cFill填充 。 若数据左对齐输出,
则在数据右边填充,否则在数据左边填充
char fill()const:返回当前使用的填充字符
设置显示精度
int precision(int np):用参数 np设置数据显示精度,
若浮点数以定点形式输出,np表示有效位数,若浮点数以科学计数法形式输出,则 np表示小数点后的位数
int precision():返回当前输出数据的精度值
16:38:22
例:输入 /输出格式控制
void main(){
cout<<"123456789012345678901234567890"<<endl;
cout.setf(ios::left); cout.width(10); cout << 55555 << endl;
cout.setf(ios::right,ios::adjustfield);
cout.width(10); cout.fill('0'); cout.setf(ios::showpos);
cout << 55555 << endl;
cout.setf(ios::internal,ios::adjustfield);
cout.width(10); cout.fill('0'); cout << -55555 << endl;
cout.setf(ios::hex,ios::basefield);
cout.setf(ios::showbase); cout << 255 << endl;
cout.setf(ios::uppercase); cout << 255 << endl;
cout.setf(ios::dec,ios::basefield);
cout.setf(ios::showpoint); cout << 5.0 << endl;
cout.setf(ios::scientific,ios::floatfield);
cout.precision(5); cout << 5234.567890213334 << endl;
int a; char b; float c;
cin.setf(ios::skipws); cin >> a >> b >> c;
cout << a << b << c << endl;
}
16:38:22
使用操纵符控制输入 /输出格式
C++的流类库中定义了一批函数,可以象普通的数据项一样嵌入输入 /
输出语句中对输入 /输出的格式进行控制操纵符 功能 I/O
endl 输出换行符,并刷新流 O
ends 输出一个空白字符,并刷新流 O
flush 刷新流 O
dec 用十进制格式输入 /输出数值数据 I/O
hex 用十六进制格式输入 /输出数值数据 I/O
oct 用八进制格式输入 /输出数值数据 I/O
ws 跳过空白字符 I
resetioflags(long lFlags) 清除 lFlags指定的格式标志位 I/O
setioflags(long lFlags) 设置 lFlags指定的格式标志位 I/O
setbase(int base) 设置进制的基数 I/O
setfill(char c) 设置填充字符 O
setprecision(int n) 设置浮点数输出精度 O
setw(int n) 设置输出宽度 O
16:38:22
例:使用操纵符控制输入 /输出格式
void main(){
const int k = 618;
cout << setw(10) << setfill('0')
<< setiosflags(ios::right) << k << endl;
cout << setw(10) << setbase(8) << setfill('*')
<< resetiosflags(ios::right)
<<setiosflags(ios::left) << k << endl;
double x = 22.07; int i;
cout << "output in fixed:" << endl;
cout << setiosflags(ios::fixed | ios::showpos);
for(i=1;i<=5;i++)
cout << setprecision(i) << x << ends;
cout << endl;
cout << "output in scientific:" << endl;
cout << resetiosflags(ios::fixed | ios::showpos)
<< setiosflags(ios::scientific);
for(i=1;i<=5;i++)
cout << setprecision(i) << x << ends;
cout << endl;
}
16:38:22
§ 4 流操作错误的检测
ios类中定义了一个记录流错误状态的成员变量,称为状态字
状态字的每一位对应流的一种错误状态,在 ios类中也定义了一些枚举常量,用于标识每一种错误状态枚举常量 值 意义
goodbit 0x00 状态正常
eofbit 0x01 文件结束
failbit 0x02 I/O操作失败,数据未丢失,可以恢复
badbit 0x04 非法操作,数据丢失,不可恢复
16:38:22
ios类中提供了以下几个与流错误状态相关的成员函数
bool eof()const;
返回 eofbit位的值 。 当遇到文件结束标志时,输入流自动设置 eofbit,该函数返回 true,否则返回 false
bool fail()const;
返回 failbit位的值 。 若流中发生格式错误,数据并没有丢失,该函数返回 true,否则未发生错误则返回 false
bool good()const;
若流中未出现任何错误,输入流也未遇到文件结束标志,
该函数返回 true,否则返回 false
bool bad()const;
bool operator!();
只要 eofbit,failbit或 badbit三个位之一被设置为 1,则该函数返回 true,否则返回 false
int rdstate() const; 返回流当前的状态字
void clear(int nState=0); 清除或设置状态字
16:38:22
字符串流
字符串流与 string类的对象或 C字符串相关联
使用字符串流对象进行输入时相当于从相关联的 string类对象或 C字符串中取数据
使用字符串流对象进行输出时相当于把数据存入相关联的
string类对象或 C字符串中
string testStr("Input test 256 * 0.5");
string s1,s2,s3;
double x,y;
istringstream input(testStr);
input >> s1 >> s2 >> x >> s3 >> y;
cout<<s1<<ends<<s2<<ends<<x<<ends<<s3<<ends<<y<<endl;
istringstream input2("Input test 256 * 0.5");
input2 >> s1 >> s2 >> x >> s3 >> y;
cout<<s1<<ends<<s2<<ends<<x<<ends<<s3<<ends<<y<<endl;
例:输入字符串流
16:38:22
例:输出字符串流
ostringstream output;
double xx,yy;
cout << "Input x:"; cin >> xx;
cout << "Input y:"; cin >> yy;
output<<xx<<" * "<<yy<<" = "<<xx*yy<< endl;
cout << output.str() << endl;
char buf[80]={0};
ostrstream output2(buf,sizeof(buf));
cout << "Input x:"; cin >> xx;
cout << "Input y:"; cin >> yy;
output2<<xx<<" * "<<yy<<" = "<<xx*yy<<endl;
cout << buf << endl;
16:38:22
§ 5 文件操作
文件程序运行过程中,需要的数据都放在内存中,程序运行结束时,这些数据都会消失,为了永久保存数据,通常把一些相关信息组织起来保存在外存中,称为文件,并用一个文件名加以标识
C++把文件看成是无结构的字节流,文件中存放的数据代表什么含义由程序员自己解释
根据文件数据的编码方式分为 文本文件 和 二进制文件可以用 ASCII码解释的文件为文本文件,非文本文件都称为二进制文件
根据存取方式分为 顺序存取文件 和 随机存取文件顺序存取文件指对文件中存放的元素顺序操作,而随机存取文件通过文件指针在文件内移动,可以查找到指定位置进行读写
16:38:22
文件流类主要有 ifstream,ofstream和 fstream等类
文件操作
读,输入数据
写,输出数据
打开文件:建立流对象与文件之间的关联关系
关闭文件:断开流对象与文件之间的关联关系
文件指针定位
16:38:22
打开文件:两种方式
1.创建流对象的同时建立与文件之间的关联关系,由流类的构造函数打开文件
ifstream::ifstream(char *name,int mode=ios::in);
ofstream::ofstream(char *name,int mode=ios::out);
fstream::fstream(char *name,int mode);
例:
ifstream infile(“c:\\datafile.dat”,ios::in);
ofstream outfile(“c:/newfile.dat”,ios::out);
2.先创建流对象,再调用 open函数打开文件例:
ifstream infile;
infile.open(“c:/boot.ini”,ios::in);
16:38:22
文件的打开方式
ios类中定义了一些枚举常量,用于表示文件的打开方式枚举常量 值 含义
ios::in 0x0001 读方式打开文件 (做输入 )
ios::out 0x0002 写方式打开文件 (做输出 )
ios::ate 0x0004 打开文件时,文件指针指向文件末尾
ios::app 0x0008 追加方式,向文件输出的内容追加到文件尾部
ios::trunc 0x0010 删除文件现有内容 (ios::out的默认操作 )
ios::nocreate 0x0020 若文件不存在,则打开操作失败
ios::noreplace 0x0040 若文件存在,则打开操作失败
ios::binary 0x0080 二进制方式打开,默认为文本方式
创建 ifstream类的对象时,默认的打开模式为 ios::in
创建 ofstream类的对象时,默认的打开模式为 ios::out
16:38:22
关闭文件
当对文件的操作完成后,应 及时关闭 文件
关闭文件操作会通知系统把缓冲区中的数据写入文件,
向文件添加结束标志,切断流对象与文件的关联关系
关闭文件使用流类的成员函数,close()
例,ifstream infile;
infile.open(“c:/boot.ini”,ios::in);
...
infile.close();
16:38:22
读文件
使用 ifstream类的对象,以 ios::in方式打开文件
两种读文件方式
用提取运算符 >> 进行输入
用成员函数进行输入
.get():读一个字符
.getline():读一行
.read():读若干个字节
istream& read(char* pch,int nCount);
istream& read(unsigned char *puch,int nCount);
istream& read(signed char *psch,int nCount);
读文件时文件指针的定位
.seekg()
.tellg()
16:38:22
例:读文件:文本文件
#include <iostream>
#include <fstream>
using namespace std;
void main(){
char ch;
ifstream input("c:/boot.ini",ios::in);
//ifstream input; input.open(“c:/boot.ini”,ios::in);
input.unsetf(ios::skipws);
while(true){
input >> ch;
if(input.eof())
break;
cout << ch;
}
input.close();
}
16:38:22
写文件
使用 ofstream类的对象,以 ios::out方式打开文件
两种写文件方式
用插入运算符 << 进行输出
用成员函数进行输出
.put():写一个字节
.write():写若干个字节
ostream& write(char * pch,int nCount);
ostream& write(unsigned char * puch,int nCount);
ostream& write(signed char * psch,int nCount);
写文件指针定位
.seekp():定位
.tellp():返回文件指针距文件开始多远
16:38:22
例:写文件:文本文件
#include <iostream>
#include <fstream>
using namespace std;
void main(){
char ch;
ifstream input("c:/boot.ini",ios::in);
ofstream output("c:/bootbak.ini",ios::out);
input.unsetf(ios::skipws);
while(true){
input >> ch;if(input.eof())break;output << ch;
}
input.close(); output.close();
input.open("c:/boot.ini",ios::in);
output.open("c:/bootbak2.ini",ios::out);
input.clear(); output.clear();
while(true){
ch = input.get(); if(input.eof())break;
output.put(ch);
}
}
16:38:22
例:写二进制文件学生的信息由姓名,学号和成绩三部分组成,从键盘输入一些学生的信息,存入文件 stud中
#include <iostream>
#include <fstream>
using namespace std;
struct student{
char name[20];
char id[20];
float score;
};
void main(){
ofstream output("stud",ios::out | ios::binary);
student stu;
while(true){
cout<<"Input name,id and score(score<0 to exit):";
cin >> stu.name >> stu.id >> stu.score;
if(stu.score<0)break;
output.write((char*)&stu,sizeof(stu));
}
output.close();
}
16:38:22
例:二进制文件的读写将上例中得到的学生数据文件进行如下操作:读出每个学生的信息进行分析,将成绩及格的学生信息写入文件 pass中,将不及格的学生信息写入文件 failure中
#include <iostream>
#include <fstream>
using namespace std;
struct student{
char name[20],id[20];
float score;
};
void main(){
ifstream input("stud",ios::in | ios::binary);
student stud;
ofstream ps("pass",ios::out | ios::binary);
ofstream fl("failure",ios::out | ios::binary);
while(true){
input.read((char *)&stud,sizeof(stud));
if(input.eof()) break;
if(stud.score>=60)ps.write((char * )&stud,sizeof(stud));
else fl.write((char *)&stud,sizeof(stud));
}
}
16:38:22
例:二进制文件的读操作
void display(char * filename){
ifstream input;
input.open(filename,ios::in | ios::binary);
student stud;
while(true)
{
input.read((char *)&stud,sizeof(stud));
if(input.eof())
break;
cout<< stud.name << ends << stud.id
<< ends << stud.score <<endl;
}
input.close();
}
16:38:22
1,C++中的输入 /输出概述 -- 概念 理解
2,C++中的流类库和流对象 -- 了解
3,格式化输入 /输出 -- 掌握
4,流操作错误的检测 -- 掌握
5,用流对象进行文件操作 -- 重点 熟练掌握
16:38:22
§ 1 C++的输入 /输出概述
C++支持两种方式的输入 /输出
兼容 C语言的方式调用 C语言的 scanf(),printf()等库函数
使用流对象的方式
C++中把数据从一个对象向另外一个对象的流动抽象成 流
流对象一般与一个文件相关联,使用流对象进行输入相当于从文件中读取数据存放于变量或对象中;使用流对象进行输出,相当于把要输出的数据写入文件中
流好比管道,从一端放进什么数据,从另一端就能取出什么数据
流提供了统一的输入 /输出操作,<< 和 >>
使用流对象进行输入时,从流对象中取出数据的操作称为 提取操作,格式为,流对象 >> 变量;
使用流对象进行输出时,把数据添加进流对象中的操作称为 插入操作,格式为,流对象 << 数据 ;
16:38:22
插入运算符与提取运算符可以分别串联使用例,cin >> a >> b >> c >> d;
cout << a <<?A? << 2.5 <<,abcde” << endl;
使用 >>输入时,用户从键盘输入的多个数据项之间可以用空格,Tab或回车分隔
<< 和 >>具有智能,能够自动判断其后数据项的类型,并采用相应的类型进行输出或输入
cin和 cout是系统预定义的流对象,分别与键盘和显示器相关联
C++中的流既提供了低级的 I/O功能,也提供了高级的 I/O
功能
低级 I/O把一切数据看做是无格式的字节序列 (字节流 ),
对字节序列不做解释,可用于实现高速大容量的数据传输
高级 I/O不把数据看做是字节流,而 把字节序列解释为各种预定义的或用户自定义的类型的数据,有一定格式
16:38:22
§ 2 流类库与流对象
C++的流类库是用继承机制建立起来的一个输入 /输出类库
主要有两个平行的基类,streambuf 和 ios
它们是所有流类的基类
streambuf
filebuf strstreambuf stdiobuf
streambuf类主要负责缓冲区的管理,提供对缓冲区的低级操作,如设置缓冲区大小,从缓冲区中提取字节,把字节插入缓冲区等
filebuf类提供文件缓冲区的管理
strstreambuf的对象使用字符串保存字符序列,提供在内存中提取和插入数据的缓冲区管理
stdiobuf提供标准 I/O文件的缓冲区管理
16:38:22
ios是抽象基类,提供输入 /输出所需的公共操作 。 类中包含一指向 streambuf类对象的指针,并提供进行格式化 I/O和设置文件模式所需的枚举常量,和对 I/O错误的处理操作
istream类提供了大部分输入操作,并重载了 >> 运算符
ios
istream ostream
ifstream istream_withassign istrstream ofstream ostream_withassign ostrstream
iostream
fstream strstream stdiostream
ifstream文件输入流类,其对象与一个文件关联,用于从该文件中输入数据
istrstream字符串输入流类,用于从其对象中提取数据
istream_withassign:预定义对象 cin所属的流类,重载了赋值运算符 =
16:38:22
ostream类及其派生类提供流的各种格式化,非格式化输出操作,对所有系统预定义的输出流重载插入运算符 <<
ofstream文件输出流类,其对象与一个文件关联,用于向该文件中插入数据
ostrstream字符串输出流类,用于把数据插入到一个该类对象,由该类对象在内存中形成一个字符串
ostream_withassign类:系统预定义的流对象 cout所属的类,重载了赋值运算符 =
16:38:22
C++推荐使用流对象的方式进行输入 /输出操作,且提供了
4个预定义的流对象,分别是,cin,cout,cerr 和 clog
cin:是 istream_withassign类的对象,标准输入流对象,
通常与标准输入设备 (键盘 )关联,可以被重定向
cout:是 ostream_withassign类的对象,标准输出流对象,
通常与标准输出设备 (显示器 )关联,可以被重定向
cerr:是 ostream_withassign类的对象,标准错误输出流对象,使用语法与 cout相似,但与监视器关联,内部无缓冲区,不能被重定向
clog:是 ostream_withassign类的对象,标准错误输出流对象,使用语法与 cout相似,与监视器关联,内部有缓冲区,不能被重定向使用流类库和流对象时,必须要包含相应的头文件,并使用命令 using namespace std;打开 std名称空间
16:38:22
§ 3 格式化输入 /输出
C++中的流支持两种方式的输入 /输出格式控制
1.使用 ios类的成员函数 2.使用操纵符
使用 ios类的成员函数进行输入 /输出格式控制
1.格式控制标志字
ios类中定义了一个成员变量,用于记录当前流的格式化状态,该成员变量称为 格式控制标志字
为了方便记忆,ios类中定义了一些格式控制枚举常量,
每个常量对应于一种输入 /输出格式
16:38:22
格式控制枚举常量标志常量 值 意义 I/O
ios::skipws 0x0001 跳过输入的空白 I
ios::left 0x0002 左对齐输出 O
ios:right 0x0004 右对齐输出 O
ios:internal 0x0008 在符号位或基指示符之后填充 O
ios::dec 0x0010 十进制格式输入 /输出 I/O
ios::oct 0x0020 八进制格式输入 /输出 I/O
ios::hex 0x0040 十六进制格式输入 /输出 I/O
ios::showbase 0x0080 输出中显示基指示符 O
ios::showpoint 0x0100 输出时显示小数点 O
ios::uppercase 0x0200 十六进制输出时用大写字母显示 O
ios::showpos 0x0400 输出正数时显示,+” O
ios::scientific 0x0800 输出时以科学计数法显示浮点数 O
ios::fixed 0x1000 定点形式显示浮点数 O
ios::unitbuf 0x2000 插入操作后立即刷新流 O
ios::stdio 0x4000 插入操作后刷新流 stdio和 stderr O
16:38:22
2.ios类中控制输入 /输出格式的成员函数
设置和返回标志字
long flags(long lFlags):用参数 lFlags的值更新标志字,
返回更新前的标志字
long flags()const:返回标志字的值
设置标志字中的某些位
log setf(long lFlags):设置参数 lFlags指定的标志位,
返回更新前的标志字的值
long setf(long lFlags,long lMasks):将参数 lMasks指定的标志位清 0,并设置参数 lFlags指定的标志位,返回更新产的标志字的值
清除标志字
long unsetf(long lFlags):将参数 lFlags指定的标志位清 0,返回更新前的标志字的值
16:38:22
设置和返回输出宽度
int width(int nw):设置输出项的显示宽度为 nw
int width()const:返回当前的输出宽度值
设置填充字符
char fill(char cFill):当设置宽度大于数据显示所需宽度时,空白位置以字符 cFill填充 。 若数据左对齐输出,
则在数据右边填充,否则在数据左边填充
char fill()const:返回当前使用的填充字符
设置显示精度
int precision(int np):用参数 np设置数据显示精度,
若浮点数以定点形式输出,np表示有效位数,若浮点数以科学计数法形式输出,则 np表示小数点后的位数
int precision():返回当前输出数据的精度值
16:38:22
例:输入 /输出格式控制
void main(){
cout<<"123456789012345678901234567890"<<endl;
cout.setf(ios::left); cout.width(10); cout << 55555 << endl;
cout.setf(ios::right,ios::adjustfield);
cout.width(10); cout.fill('0'); cout.setf(ios::showpos);
cout << 55555 << endl;
cout.setf(ios::internal,ios::adjustfield);
cout.width(10); cout.fill('0'); cout << -55555 << endl;
cout.setf(ios::hex,ios::basefield);
cout.setf(ios::showbase); cout << 255 << endl;
cout.setf(ios::uppercase); cout << 255 << endl;
cout.setf(ios::dec,ios::basefield);
cout.setf(ios::showpoint); cout << 5.0 << endl;
cout.setf(ios::scientific,ios::floatfield);
cout.precision(5); cout << 5234.567890213334 << endl;
int a; char b; float c;
cin.setf(ios::skipws); cin >> a >> b >> c;
cout << a << b << c << endl;
}
16:38:22
使用操纵符控制输入 /输出格式
C++的流类库中定义了一批函数,可以象普通的数据项一样嵌入输入 /
输出语句中对输入 /输出的格式进行控制操纵符 功能 I/O
endl 输出换行符,并刷新流 O
ends 输出一个空白字符,并刷新流 O
flush 刷新流 O
dec 用十进制格式输入 /输出数值数据 I/O
hex 用十六进制格式输入 /输出数值数据 I/O
oct 用八进制格式输入 /输出数值数据 I/O
ws 跳过空白字符 I
resetioflags(long lFlags) 清除 lFlags指定的格式标志位 I/O
setioflags(long lFlags) 设置 lFlags指定的格式标志位 I/O
setbase(int base) 设置进制的基数 I/O
setfill(char c) 设置填充字符 O
setprecision(int n) 设置浮点数输出精度 O
setw(int n) 设置输出宽度 O
16:38:22
例:使用操纵符控制输入 /输出格式
void main(){
const int k = 618;
cout << setw(10) << setfill('0')
<< setiosflags(ios::right) << k << endl;
cout << setw(10) << setbase(8) << setfill('*')
<< resetiosflags(ios::right)
<<setiosflags(ios::left) << k << endl;
double x = 22.07; int i;
cout << "output in fixed:" << endl;
cout << setiosflags(ios::fixed | ios::showpos);
for(i=1;i<=5;i++)
cout << setprecision(i) << x << ends;
cout << endl;
cout << "output in scientific:" << endl;
cout << resetiosflags(ios::fixed | ios::showpos)
<< setiosflags(ios::scientific);
for(i=1;i<=5;i++)
cout << setprecision(i) << x << ends;
cout << endl;
}
16:38:22
§ 4 流操作错误的检测
ios类中定义了一个记录流错误状态的成员变量,称为状态字
状态字的每一位对应流的一种错误状态,在 ios类中也定义了一些枚举常量,用于标识每一种错误状态枚举常量 值 意义
goodbit 0x00 状态正常
eofbit 0x01 文件结束
failbit 0x02 I/O操作失败,数据未丢失,可以恢复
badbit 0x04 非法操作,数据丢失,不可恢复
16:38:22
ios类中提供了以下几个与流错误状态相关的成员函数
bool eof()const;
返回 eofbit位的值 。 当遇到文件结束标志时,输入流自动设置 eofbit,该函数返回 true,否则返回 false
bool fail()const;
返回 failbit位的值 。 若流中发生格式错误,数据并没有丢失,该函数返回 true,否则未发生错误则返回 false
bool good()const;
若流中未出现任何错误,输入流也未遇到文件结束标志,
该函数返回 true,否则返回 false
bool bad()const;
bool operator!();
只要 eofbit,failbit或 badbit三个位之一被设置为 1,则该函数返回 true,否则返回 false
int rdstate() const; 返回流当前的状态字
void clear(int nState=0); 清除或设置状态字
16:38:22
字符串流
字符串流与 string类的对象或 C字符串相关联
使用字符串流对象进行输入时相当于从相关联的 string类对象或 C字符串中取数据
使用字符串流对象进行输出时相当于把数据存入相关联的
string类对象或 C字符串中
string testStr("Input test 256 * 0.5");
string s1,s2,s3;
double x,y;
istringstream input(testStr);
input >> s1 >> s2 >> x >> s3 >> y;
cout<<s1<<ends<<s2<<ends<<x<<ends<<s3<<ends<<y<<endl;
istringstream input2("Input test 256 * 0.5");
input2 >> s1 >> s2 >> x >> s3 >> y;
cout<<s1<<ends<<s2<<ends<<x<<ends<<s3<<ends<<y<<endl;
例:输入字符串流
16:38:22
例:输出字符串流
ostringstream output;
double xx,yy;
cout << "Input x:"; cin >> xx;
cout << "Input y:"; cin >> yy;
output<<xx<<" * "<<yy<<" = "<<xx*yy<< endl;
cout << output.str() << endl;
char buf[80]={0};
ostrstream output2(buf,sizeof(buf));
cout << "Input x:"; cin >> xx;
cout << "Input y:"; cin >> yy;
output2<<xx<<" * "<<yy<<" = "<<xx*yy<<endl;
cout << buf << endl;
16:38:22
§ 5 文件操作
文件程序运行过程中,需要的数据都放在内存中,程序运行结束时,这些数据都会消失,为了永久保存数据,通常把一些相关信息组织起来保存在外存中,称为文件,并用一个文件名加以标识
C++把文件看成是无结构的字节流,文件中存放的数据代表什么含义由程序员自己解释
根据文件数据的编码方式分为 文本文件 和 二进制文件可以用 ASCII码解释的文件为文本文件,非文本文件都称为二进制文件
根据存取方式分为 顺序存取文件 和 随机存取文件顺序存取文件指对文件中存放的元素顺序操作,而随机存取文件通过文件指针在文件内移动,可以查找到指定位置进行读写
16:38:22
文件流类主要有 ifstream,ofstream和 fstream等类
文件操作
读,输入数据
写,输出数据
打开文件:建立流对象与文件之间的关联关系
关闭文件:断开流对象与文件之间的关联关系
文件指针定位
16:38:22
打开文件:两种方式
1.创建流对象的同时建立与文件之间的关联关系,由流类的构造函数打开文件
ifstream::ifstream(char *name,int mode=ios::in);
ofstream::ofstream(char *name,int mode=ios::out);
fstream::fstream(char *name,int mode);
例:
ifstream infile(“c:\\datafile.dat”,ios::in);
ofstream outfile(“c:/newfile.dat”,ios::out);
2.先创建流对象,再调用 open函数打开文件例:
ifstream infile;
infile.open(“c:/boot.ini”,ios::in);
16:38:22
文件的打开方式
ios类中定义了一些枚举常量,用于表示文件的打开方式枚举常量 值 含义
ios::in 0x0001 读方式打开文件 (做输入 )
ios::out 0x0002 写方式打开文件 (做输出 )
ios::ate 0x0004 打开文件时,文件指针指向文件末尾
ios::app 0x0008 追加方式,向文件输出的内容追加到文件尾部
ios::trunc 0x0010 删除文件现有内容 (ios::out的默认操作 )
ios::nocreate 0x0020 若文件不存在,则打开操作失败
ios::noreplace 0x0040 若文件存在,则打开操作失败
ios::binary 0x0080 二进制方式打开,默认为文本方式
创建 ifstream类的对象时,默认的打开模式为 ios::in
创建 ofstream类的对象时,默认的打开模式为 ios::out
16:38:22
关闭文件
当对文件的操作完成后,应 及时关闭 文件
关闭文件操作会通知系统把缓冲区中的数据写入文件,
向文件添加结束标志,切断流对象与文件的关联关系
关闭文件使用流类的成员函数,close()
例,ifstream infile;
infile.open(“c:/boot.ini”,ios::in);
...
infile.close();
16:38:22
读文件
使用 ifstream类的对象,以 ios::in方式打开文件
两种读文件方式
用提取运算符 >> 进行输入
用成员函数进行输入
.get():读一个字符
.getline():读一行
.read():读若干个字节
istream& read(char* pch,int nCount);
istream& read(unsigned char *puch,int nCount);
istream& read(signed char *psch,int nCount);
读文件时文件指针的定位
.seekg()
.tellg()
16:38:22
例:读文件:文本文件
#include <iostream>
#include <fstream>
using namespace std;
void main(){
char ch;
ifstream input("c:/boot.ini",ios::in);
//ifstream input; input.open(“c:/boot.ini”,ios::in);
input.unsetf(ios::skipws);
while(true){
input >> ch;
if(input.eof())
break;
cout << ch;
}
input.close();
}
16:38:22
写文件
使用 ofstream类的对象,以 ios::out方式打开文件
两种写文件方式
用插入运算符 << 进行输出
用成员函数进行输出
.put():写一个字节
.write():写若干个字节
ostream& write(char * pch,int nCount);
ostream& write(unsigned char * puch,int nCount);
ostream& write(signed char * psch,int nCount);
写文件指针定位
.seekp():定位
.tellp():返回文件指针距文件开始多远
16:38:22
例:写文件:文本文件
#include <iostream>
#include <fstream>
using namespace std;
void main(){
char ch;
ifstream input("c:/boot.ini",ios::in);
ofstream output("c:/bootbak.ini",ios::out);
input.unsetf(ios::skipws);
while(true){
input >> ch;if(input.eof())break;output << ch;
}
input.close(); output.close();
input.open("c:/boot.ini",ios::in);
output.open("c:/bootbak2.ini",ios::out);
input.clear(); output.clear();
while(true){
ch = input.get(); if(input.eof())break;
output.put(ch);
}
}
16:38:22
例:写二进制文件学生的信息由姓名,学号和成绩三部分组成,从键盘输入一些学生的信息,存入文件 stud中
#include <iostream>
#include <fstream>
using namespace std;
struct student{
char name[20];
char id[20];
float score;
};
void main(){
ofstream output("stud",ios::out | ios::binary);
student stu;
while(true){
cout<<"Input name,id and score(score<0 to exit):";
cin >> stu.name >> stu.id >> stu.score;
if(stu.score<0)break;
output.write((char*)&stu,sizeof(stu));
}
output.close();
}
16:38:22
例:二进制文件的读写将上例中得到的学生数据文件进行如下操作:读出每个学生的信息进行分析,将成绩及格的学生信息写入文件 pass中,将不及格的学生信息写入文件 failure中
#include <iostream>
#include <fstream>
using namespace std;
struct student{
char name[20],id[20];
float score;
};
void main(){
ifstream input("stud",ios::in | ios::binary);
student stud;
ofstream ps("pass",ios::out | ios::binary);
ofstream fl("failure",ios::out | ios::binary);
while(true){
input.read((char *)&stud,sizeof(stud));
if(input.eof()) break;
if(stud.score>=60)ps.write((char * )&stud,sizeof(stud));
else fl.write((char *)&stud,sizeof(stud));
}
}
16:38:22
例:二进制文件的读操作
void display(char * filename){
ifstream input;
input.open(filename,ios::in | ios::binary);
student stud;
while(true)
{
input.read((char *)&stud,sizeof(stud));
if(input.eof())
break;
cout<< stud.name << ends << stud.id
<< ends << stud.score <<endl;
}
input.close();
}
16:38:22