【c++】文件操作

【c++】文件操作

1.      c++中的文件

2.      文件的打开和关闭

3.      文本文件的读写

4.      二进制文件的读写

5.       文件的定位

6.      文件的随机访问

参考:

《c++从入门到精通》 人民邮电出版社

扫描二维码关注公众号,回复: 1075576 查看本文章

1.C++中的文件

    在c++中,文件按存储格式分为两种类型:

        文本文件(又称ASCII码文件字符文件

        二进制文件(又称字节文件

    在字符文件中,每个字节单元的内容为字符的ASCII码。

    在字节文件中,文件内容是数据的内部表示,是从内存中直接复制过来的。

(1)对于字符信息,数据的内部表示就是ASCII码表示,所以在文本文件和二进制文件中保存的字符信息没有差别。

(2)但对于数值信息,数据的内部表示和ASCII码表示截然不同。

 

什么是文件?

    文件是相关数据的集合。计算机中的程序、数据、文档通常都组织成文件存储在外存储器中。

    由于输入输出设备具有字节流特征,所以操作系统也把他们看作是文件。例如:键盘是输入文件,显示器、打印机是输出文件。对于输入文件,只能从文件中读取数据(例如键盘);对于输出文件,智能向文件写入(例如打印机文件)。

C++如何使用文件?

    要在程序中使用文件,需要包含“#include<fstream>”命令。由它提供文件流类:

            ifstream(输入文件流类)

            ofstream(输出文件流类)

            fstream(输入输出文件流类)

    文件在c++ 看来是字符流或二进制流,统称为文件流。要使用一个文件流,应遵循以下步骤:

(1) 先打开一个文件,目的是将一个文件流对象与某个磁盘文件联系起来。

(2) 然后,使用文件流对象的成员函数,将数据写入或读出。

(3) 关闭文件,即将文件流对象与磁盘文件脱离关系。

 

2.文件的打开和关闭

   打开文件的方式有两种:
    (1)用文件流的成员函数::open()打开文件

    (2)用文件流类的构造函数打开文件

 

1)用文件流的成员函数::open()打开文件

    

    参数说明:

    第一个参数:是要打开的文件名(可含路径)

    第二个参数:指定文件的打开方式

    第三个参数:指定打开文件时的保护方式,该参数与操作系统有关,通常使用默认值filebuf::openprot。

    下表是对文件打开方式的说明。

        

(2) 用文件流类的构造函数打开文件

    ifstream、ofstream 、fstream 3个文件流类的构造函数所带有的参数与 各自的成员函数open()的参数完全相同,具体方式如下:

(3) 判断打开文件是否成功

    为了避免文件打开失败产生的异常错误,通常使用异常处理以提高程序的可靠性。判断文件打开与否的语句是:

//成员函数open()
	ifstream f1;
	f1.open("text.txt",ios::in);
	if(! f1) 
	{
		cout<<"不能打开文件"<<endl;
		exit(1); 
	}

或者:

//构造函数ifstream
	ifstream f1("text.txt",ios::in);
	if(! f1) 
	{
		cout<<"不能打开文件"<<endl;
		exit(1); 
	}

关闭文件

    文件读写完毕,通常要关闭文件,目的是把暂存在内存缓冲区中的内容写入到文件中,并归还打开文件时申请的内存资源。这有利于系统回收相应的资源。

    利用每个文件流类中的成员函数close()即可以实现关闭文件操作。

3.文本文件的读写

    对文件流对象的基本操作和标准输入输出流的操作相同,即可通过提取运算符“>>”和插入运算符“<<”来读写文件。

    程序实例:复制文本文件内容从f1->f2

//文件打开.cpp
#include<iostream> 
#include<stdio.h>
#include<fstream> 
#include<stdlib.h> // exit
using namespace std;
int main()
{
	ifstream f1("in.txt",ios::in );
	ofstream f2("out.txt",ios::out );
	if(! f1) 
	{
		cout<<"不能打开文件:in.txt"<<endl;
		exit(1); 
	}
	if(! f2) 
	{
		cout<<"不能打开文件:out.txt"<<endl;
		exit(1); 
	}
	//复制操作 
	char ch;
	while(f1>>ch)   //从f1中读取 
	{
		cout<<ch;
		f2<<ch;   //向f2输出(即写入) 
	} 
	f1.close(); 
    f2.close(); 
	return 0;
}

实验结果:

In.txt

 

Out.txt

 

4.二进制文件的读写

    对二进制文件的读写要使用到文件流的成员函数read()和write()。读写时,数据不做任何变换,直接传送。 

    读操作

    二进制文件的读,使用到文件流的成员函数read()

    这三个成员函数的功能相同,都是从二进制文件中读取n个字节数据到t指针所指的缓冲区。

注意:指针类型为字符型char*/unsigned/signed char*。其他类型的指针要做强制类型转换。

写操作

    二进制文件的写,使用到文件流的成员函数write()


    这三个成员函数的功能相同,都是t指针所指的缓冲区 写入n个字节数据 到二进制文件中。

实例:向文件中写入1-100内的偶数。

方法一:按int型字节输入
for(int i=2;i<100;i=i+2)
	{
		f1.write((char *) &i,sizeof( int )); //将整型指针转化为字符型指针 
		
	}


会发现每一个数据是占四个字节(int型),(其余三个0代表NULL空字符,用来补位)。

方法二:按char型字节数写入
for(int i=2;i<100;i=i+2)
	{
		f1.write((char *) &i,sizeof(char)); //将整型指针转化为字符型指针 
		
	}

会发现每一个数据是占1个字节(char型)。


完整实例代码如下:

//二进制文件读取.cpp
#include<iostream> 
#include<stdio.h>
#include<fstream> 
#include<stdlib.h> // exit
using namespace std;
int main()
{
	ofstream f1("out.dat",ios::out | ios::binary); //创建文件 
	
	if(! f1) 
	{
		cout<<"不能打开文件:out.dat"<<endl;
		exit(1); 
	}

	for(int i=2;i<100;i=i+2)
	{
		f1.write((char *) &i,sizeof(int)); //将整型指针转化为字符型指针 
		
	}
	f1.close(); 
    cout<<"二进制文件写入完毕!"<<endl;
    
    
    ifstream f2; 
	f2.open("out.dat",ios::in |ios::binary);  //二进制文件的读写要表明文件类型
    if(! f2) 
	{
		cout<<"不能打开文件:out.dat"<<endl;
		exit(1); 
	}
    char ch;
    f2.unsetf(ios::skipws); //跳过空格 
    while(f2>>ch)
    {
    	if((ch)==NULL) ;  //过滤空字符 
    	else  cout<<(int)ch<<" ";  //只显示非空字符 
    }
    
	return 0;
}

运行结果:

5.文件的定位

    C++把每一个文件都看成一个有序的流,如图所示,每一个文件或以EOF(文件结束符)结束,或者在特定的字节号处结束。

    当打开一个文件时,该文件就和某个文件流关联起来了。对文件进行读写实际上受到文件定位指针的控制:

        输入流的指针也称为读指针。每一次提取操作>>将从读指针当前位置开始,然后每一次提取操作自动将读指针向文件尾部移动。

        输出流的指针也称为写指针。每一次插入操作<<将从写指针当前位置开始,然后每一次插入操作,自动将写指针向文件尾部移动。

    除了顺序读写,文件流类还支持文件的随机读写,即从文件的任何位置读或写数据。在C++中,可以由程序移动文件指针,从而实现文件的随机访问,即可读写文件流中的任意一段内容。

一般文本文件很难准确定位,所以随机访问多用于二进制文件。

         

使用举例如下:

 

6.二进制文件随机读取

文件随机访问分两步:

    1. 先将文件读写位置移动到指定位置

    2. 再用文件读写函数读取或写入数据

例如:将文件指针从当前位置 后移20*4个字节,再进行读取。

核心代码:

f2.seekg(20*sizeof(int) ,ios::cur);  //将文件指针从当前位置 后移20*4个字节 
	for(int i=0;i<100&& !f2.eof(); i++)
	{
		f2.read((char *) &ch,sizeof(int )); //读取方式和写入方式相匹配 
		cout<<ch<<" ";
	}

完整代码:

//二进制文件随机读取.cpp
#include<iostream> 
#include<stdio.h>
#include<fstream> 
#include<stdlib.h> // exit
using namespace std;
int main()
{
	ofstream f1("out.dat",ios::out | ios::binary); //创建文件 
	
	if(! f1) 
	{
		cout<<"不能打开文件:out.dat"<<endl;
		exit(1); 
	}

	for(int i=2;i<100;i=i+2)
	{
		f1.write((char *) &i,sizeof(int)); //将整型指针转化为字符型指针 
		
	}
	f1.close(); 
    cout<<"二进制文件写入完毕!"<<endl;
    
    
    ifstream f2; 
	f2.open("out.dat",ios::in |ios::binary);
    if(! f2) 
	{
		cout<<"不能打开文件:out.dat"<<endl;
		exit(1); 
	}
    int ch;
    f2.seekg(20*sizeof(int) ,ios::cur);  //将文件指针从当前位置 后移10*4个字节 
	for(int i=0;i<100&& !f2.eof(); i++)
	{
		f2.read((char *) &ch,sizeof(int )); //读取方式和写入方式相匹配 
		cout<<ch<<" ";
	}

    
    
    f2.close(); 
	return 0;
}

运行结果:

从结果可发现,确实是从开头位置后移了20*4个字节,即10个int型数字后,开始读取的。

 -------------------------------------------         END      -------------------------------------

猜你喜欢

转载自blog.csdn.net/u012679707/article/details/80250798