程序设计B笔记——文件操作

11.5 文件处理

要执行文件的输入输出,须做以下几件事:
(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;}
      fout<<10<<"  "<<123.456<<"  "<<"This is a text file.\n";
      fout.close();
      return 0;
} 

a.is_open()函数, 该函数用来判断文件打开是否成功(建立文件信息区)。也可以通过判断流的状态 if(fout.fail()): if(! fout.good())
还可以采用:if(! fout):测定 对象 a 是否 建立/存在(fstream 类对象不能使用这种方式)

文件读写例子

#include<fstream>
using namespace std;
int main(){
    ofstream  fout;char filename[20];cin>>filename;
     fout.open(filename,ios::out);//建立文件信息区	
      if (! fout.is_open()){   cout<<"Cannot open output file\n,"; return 1;}
      fout<<10<<"  "<<123.456<<"  "<<"This is a text file.\n";
      fout.close();
      return 0;
} 

文件读写例子

#include<fstream>
#include <string>	
using namespace std;
int main(){
    ofstream  fout;string filename;cin>>filename;
     fout.open(filename.c_str(),ios::out);//将字符串对象转化为字符数组	
      if (! fout.is_open()){   cout<<"Cannot open output file\n,"; return 1;}
      fout<<10<<"  "<<123.456<<"  "<<"This is a text file.\n";
      fout.close();
      return 0;
} 

1.文件打开

open()函数原型在fstream中定义,函数原型如下:

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::app    = 0x08, //供写,文件不存在则创建,若文件已存在则在原文件内容后写入新的内容,指针位置总在最后
ios::trunc   = 0x10, //在读写前先将文件长度截断为0(默认)
ios::binary  = 0x80  //二进制格式文件

ios::in: 用于输入。文件以输入方式打开
ifstream流类的默认打开方式
文件存在,打开文件;
文件不存在,打开失败。

ios::out: 用于输出。文件以输出方式打开。
ofstream流类的默认打开方式
如果文件存在,打开文件,并清空原文件中的内容
如果文件不存在,则创建文件
如果文件路径错误,创建流对象操作失败。

ios::app: 以追加的方式打开文件。主要用于文件的操作。如果文件不存在,则创建文件。如果文件存在,则不会删除文件中的内容
在该模式下,不管文件指针处于何处,新写入的内容永远在文件尾。

int main(){
	fstream f;
	f.open("result.txt",ios::app);
	f.put('d');
       f.seekp(ios::beg);//移动文件写指针到文件开始
       f.put(‘e’); //文件写操作仍在文件尾部
	return 0;
}

2.关闭文件

关闭文件操作包括把缓冲区数据完整地写入文件添加文件结束标志
切断流对象和外部文件的连接
若流对象的生存期没有结束,可以重用
当一个流对象的生存期结束,系统也会自动关闭文件

    ofstream  ofile ;	
    ofile . open ( "myfile1" ) ;
    ……		
    ofile . close ( ) ;	
    ofile . open ( "myfile2" );

11.5.3 文本文件

文本文件用默认方式打开
文本文件用文件流对象(文本文件流)进行读/写操作
文本文件是顺序存取文件

struct student		//定义记录,一条记录反映了一个对象的基本信息
{
      int number ; 
      string name ;
      int score ;  
};

通常一个逻辑记录换行符分隔数据项之间可以用空白符换行符制表符等分隔
文件中只存储了数据,没有存储记录的逻辑结构
每条记录的长度是不同
只能顺序访问每一条记录(数据对象)

把文件 d:\test 复制到文件 d:\testnew 中

#include<iostream>
#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 ) ;//读一个字符,写一个字符
   f1.close () ;
   f2.close () ;
   cout << "It is over !\n" ;
}

11.5.4 二进制文件

  • 二进制文件以基本类型数据在内存的二进制表示形式存放数据,不对写入或读出的数据做格式转换
  • 二进制文件的读写方式由程序控制
  • 打开二进制文件用binary方式
  • 二进制文件是随机存取文件
struct student		//定义记录,一条记录反映了一个对象的基本信息
{
       int number ; 
       char  name[20] ;//不用string是因为string不是定长的
       int score ;  
};

文件中只存储了数据,没有存储记录的逻辑结构
每条记录的长度是相同
可以随机访问每一条记录

用read()函数和write()函数读写文件 (成块的读写)

可以成块(若干字节)进行读写操作
读写的过程中不进行转换(不存在二进制流到文本流得转换)
适用于二进制文件。

read()和write()原型如下:

 istream &read(unsigned char* buf,int num);//(内存中的位置,连续处理多少个字节)
 ostream &write(const unsigned char* buf,int num); 

例 用write()函数向文件test中写入整数与双精度数。

#include<fstream.h>
int main(){
    ofstream  out(“f:\\test.dat”,ios::binary);
     if (!out) {return 1; }
     int i=12340; double num=100.45;
     out.write((char *) &i,sizeof(int));
     out.write((char *) &num,sizeof(double));
     out.close();
    ifstream in("f:\\test.dat");
     if (!in)  {return 1; }
     int j;double d; 
     in.read((char *)&j,sizeof(int));
     in.read((char *)&d,sizeof(double));
     cout<<j<<" "<<d<<endl;
     in.close();return 0; } 

例 从键盘输入若干个学生的有关数据,然后把它们转存到磁盘文件上去。

#include <fstream>
#include <iostream>
using namespace std;
class Student{
	char name[10];	int num;	int age;	char addr[20];
	
public:
	friend ostream & operator <<(ostream &out,Student &obj){	out<<obj.name<<"\t"<<obj.num<<"\t"<<obj.age<<"\t"<<obj.addr<<endl;
		return out;	}
	friend istream& operator >>(istream & in,Student obj)	{
		in>>obj.name>>obj.num>>obj.age>>obj.addr;
		return in;	}

}; 
class Student_list
{
	Student stud[1000]; 
	int number;
public:
	Student_list();
	void input();
	void display() ;
	~Student_list();
};
Student_list::Student_list(){
	fstream fin("stu.dat",ios::in|ios::binary);
	int i=0;
	number=i;
	if(!fin)	return ;
	fin.read ((char *)&stud[i],sizeof(Student));   
	while(!fin.eof())//判断是否到文件尾
{
		i++;
		fin.read ((char *)&stud[i],sizeof(Student));   
	}
	number=i;
   fin.close ();
   return ;
}
void Student_list::input()
{
	cin>>stud[number++];
}
void Student_list::display()
{
	for (int i=0;i<number; i++)
		cout<<stud[i];
	return ;
}
Student_list::~Student_list()
{
	fstream fout("stu.dat",ios::out|ios::binary);
	if(!fout)      
	{
		cout<<"cannot open file\n";
		return;
	}
	for(int i=0;i<number;i++)
		fout.write((char *)&stud[i],sizeof(Student));
           //fout.write((char *) stud, number*sizeof(Student));
    fout.close();
}
int main()
{
	Student_list s_list;
	while(1)
	{
		s_list.input();
		cout<<"Continue(Y/N)?";
		char ch;
		cin>>ch;
		if(ch=='N' || ch=='n')
			break;
	}
	s_list.display();
	return 0;
}

文件的随机读写

在C++的I/O系统中有个文件指针,它有两个名字。
其中一个名字叫get指针,用于指出下一次输入操作的位置;
另一个名字叫做put指针,用于指出下一次输出操作的位置

istream 类操作流读指针的成员函数

 istream & istream :: seekg ( long  pos) ;
作用:读指针从流的起始位置向后移动由pos指定字节
 istream & istream :: seekg ( long off, ios::seek_dir ) ;
作用:读指针从流的seek_dir位置移动 off 指定字节

ios::seek_dir 值:
cur 相对于当前读指针所指定的当前位置
beg 相对于流的开始位置
end 相对于流的结尾处
enum ios::seek_dir { beg = 0 ; cur = 1 , end = 2 }

 istream & istream :: tellg () ;
作用	返回读指针当前所指位置值

命令行参数
C++程序的main函数可以添加参数,即main函数的原型为:

int main(int argc, char* argv[]);

argc:接受字符串的个数
argv[]:接受程序作为命令行执行时输入的字符串

例如,若exe文件名为testmain,在命令窗口输入:
testmain aaa bbb ccc
则有: argv[0] 为 “testmain”
argv[1] 为 “aaa”
argv[2] 为 “bbb”
argv[3] 为 “ccc”
argc 为 4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值