C++流和文件流操作

在程序设计中,数据输入/输出(I/O)操作是必不可少的,C++语言的数据输入/输出操作是通过I/O流库来实现的。C++中把数据之间的传输操作称为流,流既可以表示数据从内存传送到某个载体或设备中,即输出流,也可以表示数据从某个载体或设备传送到内存缓冲区变量中,即输入流。在进行I/O操作时,首先是打开操作,使流和文件发生联系,建立联系后的文件才允许数据流入和流出,输入或输出结束后,使用关闭操作使文件与流断开联系。
标准输入输出流(cout、cin)在使用过程中,只要在程序的开头嵌入相应的头文件“iostream.h”即可。
文件的打开和关闭是通过使用fstream类的成员函数open和close来实现的,fstream类用来对文件流进行操作,fstream类的头文件是fstream.h。
cout是标准输出设备即显示器(默认设备)连接的预定义输出流。C++语言的插入运算符“<<”向输出流发送字符,cout是数据的目的地,插入运算符“<<”把数据传送到cout。
输出流对象cout输出数据的语句格式为:
cout<<数据1<<数据2<<……<<数据n;
其中,“<<”是输出操作符,用于向cout输出流中插入数据。
在cout中还可以使用流控制符控制数据的输出格式,但要注意使用这些流控制符时,要在程序的开始部分嵌入头文件“iomanip.h”。
常用的流控制符及其功能如下表所示:
表1  I/O流的常用控制符
  
Dec
十进制数输出
Hex
十六进制输出
Oct
八进制数输出
setfill©
在给定的输出域宽度内填充字符c
setprecison(n)
设显示小数精度为n位
setw(n)
设域宽为n个字符
setiosflags(ios::fixed)
固定的浮点显示
setiosflags(ios::scientific)
指数显示
setiosflags(ios::left)
左对齐
setiosflags(ios::right)
右对齐
setiosflags(ios::skipws)
忽略前导空白
setiosflags(ios::uppercase)
十六进制数大写输出
setiosflags(ios::lowercase)
十六进制数小写输出
setiosflags(ios::showbase)
 
当按十六进制输出数据时,前面显示前导符0x;当按八进制输出数据时,前面显示前导符0
Endl
输入一个换行符并刷新流
cin是与标准输入设备即键盘(默认设备)连接的预定义输入流。它从输入流中取出数据,数据从输入提起运算符“>>”处流进程序。
输入流对象cin输入数据的语句格式为:
cin>>变量名1>>变量名2>>……>>变量名n;
其中,“>>”是输入操作符,用于从cin输入流中取得数据,并将取得的数据传送给其后的变量,从而完成输入数据的功能。
注意:“>>”操作符后除了变量名外不得有其他数字、字符串,否则系统会报错。
文件是存储在磁盘、磁带等外部设备上的数据的集合,每一个文件都必须有一个唯一的文件名称。在使用文件前必须首先打开文件,使用完毕后必须关闭文件。对文件的操作是由文件流类完成的。文件流类在流与文件之间建立连接。下图是与文件操作相关的类及其继承关系。
ios
istream
ostream
ifstream
iostream
ofstream
fstream
ios
istream
ostream
ifstream
iostream
ofstream
fstream
图1 几个与文件处理相关的类及其继承关系结构图
下表是常用的I/O流类库的说明,以及在编程中需要包含到程序中的头文件。
表2 常用I/O流类库说明
 
 
编程中需要包含的头文件
ios
流基类,是抽象类
ostream.h
istream
通用输入流类和其它输入流类的基类
iostream.h
ifstream
输入文件流类
fstream.h
ostream
通用输出流类和其它输出流类的基类
iosream.h.
ofstream
输出文件流类
fstream.h
iostream
通用I/O流类和其它I/O流的基类
iostream.h
fstream
I/O文件流类
fstream.h
对文件的操作是由文件流类完成的。文件流类在流与文件间建立连接。由于文件流分为三种:文件输入流、文件输出流、文件输入/输出流,所以相应的必须将文件流说明为ifstream、ofstream和fstream类的对象,然后利用文件流的对象对文件进行操作。
对文件的操作过程可按照一下四步进行:即定义文件流类的对象、打开文件、堆文件进行读写操作、关闭文件,下面分别进行介绍。
(1)定义文件流对象
利用文件流类可以定义文件流类对象,方法是:
文件流类 对象名;
如:
ifstream ifile; //定义一个文件输入流对象
ofstream ofile; //定义一个文件输出流对象
fstream iofile; //定义一个文件输出/输入流对象
(2)打开文件
定义了文件流对象后,就可以利用其成员函数open()打开需要操作的文件,该成员函数的函数原型为:
void open(const unsigned char *filename,int mode,int access=filebuf:openprot);
其中:filename是一个字符型指针,指定了要打开的文件名;mode指定了文件的打开方式,其值如下表所示;access指定了文件的系统属性,其取值为:
0        一般文件
1        只读文件:
2        隐藏文件
3        系统文件
表3 在ios类中定义的文件打开方式
文件打开方式
 
ios::in
以输入(读)方式打开文件
ios::out
以输出(写)方式打开文件
ios::app
打开一个文件使新的内容始终添加在文件的末尾
ios::ate
打开一个文件使新的内容添加在文件尾,但下次添加时,写在当前位置处
ios::trunc
若文件存在,则清除文件所有内容;若文件不存在,则创建新文件
ios::binary
以二进制方式打开文件,缺省时以文本方式打开文件
ios::nocreate
打开一个已有文件,若该文件不存在,则打开失败
ios::noreplace
若打开的文件已经存在,则打开失败
说明:
1)在实际使用过程中,可以根据需要将以上打开文件的方式用“|”组合起来。如:
ios::in|ios::out                表示以读/写方式打开文件
ios::in|ios:: binary             表示以二进制读方式打开文件
ios::out|ios:: binary            表示以二进制写方式打开文件
ios::in|ios::out|ios::binary       表示以二进制读/写方式打开文件
2)如果未指明以二进制方式打开文件,则默认是以文本方式打开文件。
3)对于ifstream流,mode参数的默认值为ios::in,对于ofstream流,mode的默认值为ios::out。
(3)文件的关闭
在文件操作结束(即读、写完毕)时应及时调用成员函数close()来关闭文件。该函数比较简单,没有参数和返回值。
利用对象和相应的成员函数对文件进行读写操作,我们将单独介绍。
在打开文件后就可以对文件进行读写操作了。从一个文件中读出数据,可以使用文件流类的get、getline、read成员函数以及运算符“>>”;而向一个文件写入数据,可以使用其put、write函数以及插入符“<<”,如下表所示:
表4 文件流类的文件操作成员函数
函数原型
 
get(char &ch)
从文件中读取一个字符
getline(char *pch,int count,char delim=’/n’)
从文件中读取多个字符,读取个数有参数count决定,参数delim 是读取字符是指定的结束符(默认为换行字符)
read(char *pch,int count)
从文件中读取多个字符,读取个数由参数counnt决定
put(char ch)
向文件写入一个字符
write(const char *pch,int count)
向文件写入多个字符,字符个数由count决定
顺序文件操作:这种操作方式只能从文件的开始处依次顺序读写文件内容,而不能任意读写文件内容。
从一个文件中读出数据,可以使用get、getline、read成员函数以及运算符“>>”;而向一个文件写入数据,可以使用put、write成员函数以及插入符“<<”。



fstream  // 文件流
ifstream  // 输入文件流
ofstream  // 输出文件流

//创建一个文本文件并写入信息
//同向屏幕上输出信息一样将信息输出至文件

#include<iomanip.h>
#include<fstream.h>
void main()
{
ofstream f1("d://me.txt");           //打开文件用于写,若文件不存在就创建它
if(!f1)return;                 //打开文件失败则结束运行
f1<<setw(20)<<"姓名:"<<"廉东方"<<endl;     //使用插入运算符写文件内容
f1<<setw(20)<<"家庭地址:"<<"河南郑州"<<endl;
f1.close();                   //关闭文件
}
运行后打开文件d:/me.txt,其内容如下:
姓名:廉东方
家庭地址:河南郑州

文件操作:
打开文件
文件名
注意路径名中的斜杠要双写,如:
"D://MyFiles//ReadMe.txt"
文件打开方式选项:
ios::in    = 0x01, //供读,文件不存在则创建(ifstream默认的打开方式)
ios::out    = 0x02, //供写,文件不存在则创建,若文件已存在则清空原内容(ofstream默认的打开方式)
ios::ate    = 0x04, //文件打开时,指针在文件最后。可改变指针的位置,常和in、out联合使用
ios::app    = 0x08, //供写,文件不存在则创建,若文件已存在则在原文件内容后写入新的内容,指针位置总在最后
ios::trunc   = 0x10, //在读写前先将文件长度截断为0(默认)
ios::nocreate = 0x20, //文件不存在时产生错误,常和in或app联合使用
ios::noreplace = 0x40, //文件存在时产生错误,常和out联合使用
ios::binary  = 0x80  //二进制格式文件
文件保护方式选择项:
filebuf::openprot;   //默认的兼容共享方式
filebuf::sh_none;    //独占,不共享
filebuf::sh_read;    //读共享
filebuf::sh_write;   //写共享
打开文件的方法
调用构造函数时指定文件名和打开模式
ifstream f("d://12.txt",ios::nocreate);         //默认以 ios::in 的方式打开文件,文件不存在时操作失败
ofstream f("d://12.txt");                //默认以 ios::out的方式打开文件
fstream f("d://12.dat",ios::in|ios::out|ios::binary); //以读写方式打开二进制文件
使用Open成员函数
fstream f;
f.open("d://12.txt",ios::out);             //利用同一对象对多个文件进行操作时要用到open函数
检查是否成功打开
成功:
if(f){...}       //对ifstream、ofstream对象可用,fstream对象不可用。
if(f.good()){...}
失败:
if(!f){...}       // !运算符已经重载
if(f.fail()){...}
读写操作
使用<<,>>运算符
只能进行文本文件的读写操作,用于二进制文件可能会产生错误。
使用函数成员 get、put、read、write等
经常和read配合使用的函数是gcount(),用来获得实际读取的字节数。
读写二进制文件注意事项
打开方式中必须指定ios::binary,否则读写会出错
用read/write进行读写操作,而不能使用插入、提取运算符进行操作,否则会出错。
使用eof()函数检测文件是否读结束,使用gcount()获得实际读取的字节数
关闭文件
使用成员函数close,如:
f.close(); 
利用析构函数
对象生命期结束时会检查文件是否关闭,对没有关闭的文件进行关闭操作。
随机读写文件
通过移动文件读写指针,可在文件指定位置进行读写。
seekg(绝对位置);      //绝对移动,    //输入流操作
seekg(相对位置,参照位置);  //相对操作
tellg();          //返回当前指针位置
seekp(绝对位置);      //绝对移动,    //输出流操作
seekp(相对位置,参照位置);  //相对操作   
tellp();          //返回当前指针位置
参照位置:
ios::beg  = 0       //相对于文件头
ios::cur  = 1       //相对于当前位置
ios::end  = 2       //相对于文件尾
读写文本文件的示例
//为能够正确读出写入文件的各数据,各数据间最好要有分隔
#include<fstream.h>
void main()
{
fstream f("d://try.txt",ios::out);
f<<1234<<' '<<3.14<<'A'<<"How are you"; //写入数据
f.close();
f.open("d://try.txt",ios::in);
int i;
double d;
char c;
char s[20];
f>>i>>d>>c;               //读取数据
f.getline(s,20);
cout<<i<<endl;             //显示各数据
cout<<d<<endl;
cout<<c<<endl;
cout<<s<<endl;
f.close();
}
运行结果:
1234
3.14
A
How are you
Press any key to continue
显示文本文件的内容
//使用get()一次读一个字符--------------------------------方案一
#include<fstream.h>
void main()
{
ifstream fin("d://简介.txt",ios::nocreate);
if(!fin){
cout<<"File open error!/n";
return;
}
char c;
while((c=fin.get())!=EOF)cout<<c;    //注意结束条件的判断
fin.close();
}
//使用get(char *,int n,char delim='/n')一次读多个字符----方案二
//巧妙利用文本文件中不会有字符'/0'的特点进行读取

#include<fstream.h>
void main()
{
ifstream fin("d://简介.txt",ios::nocreate);
if(!fin){
cout<<"File open error!/n";
return;
}
char c[80];
while(fin.get(c,80,'/0')!=NULL)cout<<c; //注意结束条件的判断
fin.close();
}
//使用read(char *,int n)读文件---------------------------方案三
#include<fstream.h>
void main()
{
ifstream fin("d://简介.txt",ios::nocreate);
if(!fin){
cout<<"File open error!/n";
return;
}
char c[80];
while(!fin.eof())            //判断文件是否读结束
{
fin.read(c,80);
cout.write(c,fin.gcount());
}
fin.close();
}
拷贝文件
//二进制文件操作示例

#include<fstream.h>
void main()
{
ifstream fin("C://1.exe",ios::nocreate|ios::binary);
if(!fin){
cout<<"File open error!/n";
return;
}
ofstream fout("C://2.exe",ios::binary);
char c[1024];
while(!fin.eof())
{
fin.read(c,1024);
fout.write(c,fin.gcount());
}
fin.close();
fout.close();
cout<<"Copy over!/n";
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值