要执行文件的输入输出,须做以下几件事:
(1) 在程序中包含头文件fstream;
(2) 建立文件流。建立文件流的过程就是定义流类的对象,例如:
ifstream in;//读文件
ofstream out;//写文件
fstream both;//读/写文件
分别定义了输入流对象in;输出流对象out,输入输出流对象both。
(3) 使用open()函数打开文件,也就是使某一文件与上面的某一流相联系。open()函数是上述三个流类的成员函数,其原型是在fstream.h中定义的, 原型为:
void open(const unsigned char*,int mode,int access=filebuf::openprot);
(4) 对open结果进行检查(检查打开操作是否成功。可省略,但不推荐。)
(5)进行读写。在建立(或打开)的文件上执行所要求的输入或输出操作;
(6)关闭文件流对象。
//写文件
#include<fstream>
using namespace std;
int main(){
ofstream fout;
fout.open("f:\\test.txt",ios::out);
//建立文件信息区 ,可以是绝对路径也可以是相对路径,注意:是双斜杠\\ !!!
if (! fout.is_open()){ cout<<"Cannot open output file\n,"; return 1;}
//return 1;该函数非正常终止
fout<<10<<" "<<123.456<<" "<<"This is a text file.\n";
fout.close();
return 0;
}
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
ofstream fout;char filename[20];cin>>filename;
fout.open(filename,ios::out);//建立文件信息区,键盘输入存入字符数组中。
/*
string filename;cin>>filename;
fout.open(filename.c_str(),ios::out);
//建立文件信息区,c_str()把字符串对象转换成字符数组
*/
if (! fout.is_open()){ fout<<"Cannot open output file\n,"; return 1;}
fout<<10<<" "<<123.456<<" "<<"This is a text file.\n";
fout.close();
return 0;
}
1.文件打开
open函数原型:
void open (char* filename, int mode, int access=0)
第一个参数用于传递文件名;
字符数组
第二个参数mode值表示文件的使用方式;
第三个参数打开文件的共享方式
filebuf::openprot; //默认的兼容共享方式(与MS_DOS文件兼容)
filebuf::sh_none; //独占,不共享
filebuf::sh_read; //读共享
filebuf::sh_write; //写共享
文件打开方式
ios::in = 0x01,
输入,供读, (ifstream默认的打开方式)
ios::out = 0x02,
输出,供写,文件不存在则创建,
若文件已存在则清空原内容(ofstream默认的打开方式)
如果文件路径错误,创建流对象操作失败。
ios::ate = 0x04,
文件末尾增加新内容。文件打开时,指针在文件尾部。
可改变指针的位置,常和in、out联合使用
ios::binary = 0x80
//二进制格式文件(如exe文件)
ios::app:
以追加的方式打开文件。主要用于文件的写操作。
如果文件不存在,则创建文件。如果文件存在,则不会删除文件中的内容,
在该模式下,不管文件指针处于何处,新写入的内容永远在文件尾。
2.关闭文件
关闭文件操作:
包括把缓冲区数据完整地写入文件,
添加文件结束标志,
切断流对象和外部文件的连接。
若流对象的生存期没有结束,可以重用
当一个流对象的生存期结束,系统也会自动关闭文件 。
(文件操作结束以后,随时关闭流对象)
#include<iostream>
#include<fstream>
using namespace std;
int main ( ){
ofstream ost ;
ost . open ( "d:\\my1.dat ") ;
ost << 20 << endl ;
ost << 30.5 << endl ;
ost . close ( ) ;
ifstream ist ( "d:\\my1.dat" ) ;
int n ;
double d ;
ist >> n >> d ; //(顺序:怎么存的,怎么读出。读文件按照写文件顺序)
cout << n << endl << d << endl ;
}
3.文本文件
文本文件用默认方式打开
文本文件用文件流对象(文本文件流)进行读/写操作
文本文件是顺序存取文件
#include<iostream>
#include<fstream>
//写文件
using namespace std;
int main(){
ofstream out( "d:\\test" ) ;//创建文件的时候把打开文件的参数写上
if ( !out )//如果流对象为空,没创建好
{return 1;}
out << 10 << " " << 123.45 << " " ;
out << "\nThis is a short text file." ;
out.close () ;
return 0 ;
}
#include<iostream>
#include<istream>
#include <fstream>
//读文件
using namespace std;
int main (){
char ch ;
int i ;
float f ;
char str1 [ 10 ] , str2 [ 10 ] ;
ifstream in ( "d:\\test" ) ;
if ( ! in ) {return 0 ; }//行末不要有空格,不作为单独项
in >> i >> f >> ch >> str1 >> str2 ;
cout << i << " " << f << " " << ch << '\n' ;
cout << str1 << str2 << endl ;
in.close () ;
}
注意:行末尾不要有空格!
文件复制操作:把文件 d:\test 复制到文件 d:\testnew 中
#include<iostream>
#include<istream>
#include <fstream>
//文件复制
using namespace std;
int main ( ){
char ch ;
ifstream f1 ( "d:\\test" ) ;
if ( !f1 ) {return 0; }
ofstream f2 ( "d:\\testnew" ) ;
if ( !f2 ) {return 0; }
while ( f1 && f1.get(ch) ) f2.put( ch ) ;
//get得到一个字符,put输出一个字符,以字符为单位操作
f1.close () ;
f2.close () ;
cout << "It is over !\n" ;
}
举例:
利用类对文件操作进行封装,
实现学生信息文件内容的显示,文件中添加记录等基本的操作。
#include<bits/stdc++.h>
using namespace std;
struct student{
string name ;
int number , score ;
};
class FileOperation{
string filename;
student record[100]; //假设文件中存储的及记录个数不超过100
int num;//存储记录的个数
public:
FileOperation();//构造函数:初始化数据成员;创建文件通道。读操作
void display();
void append();//追加学生记录
~FileOperation();//析构函数:写操作
};
FileOperation::FileOperation(){
cin>>filename;
ifstream instuf( filename.c_str(), ios::in ) ;//c_str()把字符串对象转换成字符数组
num=0;
if ( !instuf )
{exit(0); }
instuf >> record[num].number >> record[num].name >> record[num].score;
//按顺序
while(!instuf.eof() ) {//eof()判断是否读到文件尾
num++;
instuf >> record[num].number >> record[num].name >> record[num].score;
}
instuf.close();
}
void FileOperation::display()
{
cout<<"number"<<"\t"<<"name"<<"\t"<<"score"<<endl;//表头
for(int i=0;i<num;i++)
cout << record[i].number << '\t' << record[i].name << '\t' << record[i].score << '\n' ;
}
void FileOperation::append()
{
cin>>record[num].number>>record[num].name>>record[num].score;
//键盘输入数据写入对象数组中
num++;
}
FileOperation::~FileOperation(){
ofstream outstuf ;
outstuf.open( filename.c_str(), ios::out ) ;
if ( !outstuf )
abort();
for(int i=0;i<num;i++)
outstuf << record[i].number << ' ' << record[i].name << ' ' << record[i].score << '\n' ;
outstuf.close() ;
}
int main()
{
FileOperation f;
f.append();
f.display();
return 0;
}
/*
abort()立即结束,不做任何操作.
exit(): 释放所有静态全局的对象、缓存,关掉所有的I/O通道,然后终止程序。
*/
4.二进制文件(对复杂数据类型不友好,数据要定长,不建议使用)
二进制文件以基本类型数据在内存的二进制表示形式存放数据,不对写入或读出的数据做格式转换
二进制文件的读写方式由程序控制
打开二进制文件用binary方式
二进制文件是随机存取文件(定长的)
用read()函数和write()函数读写文件 (成块的读写)
read()和write()原型如下:
istream &read(unsigned char* buf,int num);
ostream &write(const unsigned char* buf,int num);
参数1:内存中的位置;参数2:连续处理多少个字节。
注意:文件中的数据与内存中的数据不一定相同。从文件读数据到内存,此时文件与内存内容一致,但可以通过函数改变内存中的数据,操作后,文件与内存内容不一致;为保持一致,将内存写回文件。
二进制可以随机读写:(通过移动文件指针实现)
在C++的I/O系统中有个文件指针,它有两个名字。
其中一个名字叫get指针,用于指出下一次输入操作的位置;
另一个名字叫做put指针,用于指出下一次输出操作的位置。
命令行参数:(主函数可以带参数)