C++文件操作

本文介绍了C++中用于文件操作的几个基本类,包括basic_filebuf、basic_ofstream、basic_ifstream和basic_fstream,详细讲解了它们的构造函数和文件打开模式。此外,还阐述了文件的打开、关闭、读写操作,包括文本和二进制文件的处理方法,以及如何判断文件结束的eof()函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、文件输入输出类简述

       在头文件fstream中声明了如下类:

        basic_filebuf      basic_ofstream       basic_ifstream       basic_fstream

       这些类提供了文件输入和输出的高层接口,其中的basic_filebuf提供了对文件的缓冲访问


      1.1  basic_ofstream

             basic_ofstream是从basic_ostream派生而来的模板类,包含了将输出文件和basic_ofstream流关联起来的构造函数和成员函数。basic_ofstream从basic_ostream继承了在 输出流中写入数据和在输出流中进行移动的成员函数。

             可定义如下形式的构造函数

             explicit  basic_ofstream(const char* filename, ios_base::openmode mode = ios_base::out)

             将一个basic_ofstream对象以mode模式打开的文件filename相关联。类型openmode是一个bitmask类型。

             ofstream的构造函数   basic_ofstream(const char* filename) 其默认的文件打开模式是输出方式。

             在ofstream类中,iso_base::out是指定和默认的打开模式,如果指定了其他打开模式,该模式将与iso_base::out一起应用到这个文件。如果文件不能打开,则设置failbit标志。


     1.2  basic_ifstream

             basic_ifstream是从basic_istream派生而来的模板类,包含了将输入文件和basic_ifstream流关联起来的构造函数和成员函数。basic_ifstream从basic_istream继承了读取输入流数据及在输入流中进行移动的成员函数。

             可定义如下形式的构造函数

             explicit  basic_ifstream(const char* filename, ios_base::openmode mode = ios_base::in)

             ifstream的构造函数   basic_ifstream(const char* filename) 其默认的文件打开模式是输入方式。

             在ifstream类中,iso_base::in是指定和默认的打开模式,如果指定了其他打开模式,该模式将与iso_base::in一起应用到这个文件。如果文件不能打开,则设置failbit标志。


     1.3  basic_fstream

             basic_fstream是从basic_iostream派生而来的模板类,包含了将输入文件和basic_fstream流关联起来的构造函数和成员函数。basic_fstream从basic_iostream继承了读写文件数据及在文件中移动的成员函数。

             可定义如下形式的构造函数

             explicit  basic_fstream(const char* filename, ios_base::openmode mode = ios_base::in | ios_base::out)

             fstream的构造函数   basic_fstream(const char* filename) 其默认的文件打开模式是输入/输出方式。



二、打开文件

      在ifstream,ofstream,fstream类中都有一个成员函数open,可用于打开文件,函数原型为

      void  open(const char* filename, int mode)

      其中 filename 指的是文件名, mode是要打开文件的方式

      打开文件的方式在类ios(是所有流式I/O类的基类)中定义,常用的值如下:

      ios::app  :                     以追加的方式打开文件

      ios::ate   :                     文件打开后定位到文件尾,ios::app就包含有此属性

      ios::binary  :                以二进制方式打开文件,缺省的方式是文本方式。

      ios::in  :                         文件以输入方式打开

      ios::out  :                      文件以输出方式打开

      ios::nocreate  :           不建立文件,所以文件不存在时打开失败

      ios::noreplace :          不覆盖文件,所以打开文件时如果文件存在失败

      ios::trunc  :                  如果文件存在,把文件长度设为0

      对于以上打开方式,可用 “ | ” 把上面打开方式连接起来,如一追加,输出及二进制方式打开文件,可表示为   ios::app|ios::out|ios::binary

    

      //******************注意

      网络上查到的很多关于open函数的原型是

      void open(const char* filename, int mode, int access);

      在这里参数filename,mode和上面所述一样,access指的是 打开属性

      打开文件的属性取值可以是:

      0 : 普通文件,打开访问

      1 : 只读文件

      2 : 隐含文件

      4 :系统文件

      可以用 " | " 或是 “ + ” 将上面属性连起来


     但我在实际编写中发现,在gcc4.4.3版本下,open函数原型是不包括access参数的,所以也就是说执行函数open(filename,mode,access)会报错,而正确执行是open(filename,mode)。另外对于mode,也发现iso::nocreate是不存在的。大概这些改动对于更高版本的gcc也是成立的吧。网上的很多资料大概也是相对较老版本所撰写的。所以在执行函数时有必要注意这两种情况。

    *************************************************************************//



三、文件关闭

      每次执行文件操作时,文件打开后都需要执行文件关闭操作。文件关闭的函数原型为

      void close();

      虽然在进程结束时,文件会被自动关闭。但系统能够打开的文件数及进程能够打开的文件数是有限的,关闭文件句柄时,会将输出缓冲区的内容刷新到文件中,如果进程意外结束,可能会造成输出缓冲区的内容丢失从而造成文件内容的丢失,所以在文件操作完成时,应养成习惯关闭文件。



四、读写文件

    文件读写分为文本文件读写和二进制文件读写。

  

   1.文本文件读写

     文本文件读写可直接用插入器(<<)向文件输出,用析取器(>>)从文件输入

     如下代码展示向file1输入“test”,从file2读入一个整数

      
#include <iostream>
#include <fstream>
using namespace std;

int main(){
	fstream  file1, file2;

	file1.open("file1",ios::out);
	file2.open("file2",ios::in);

	file1<<"test";
	
	int i;
	file2>>i;
}


   2.二进制文件读写

    ①put()
  put()函数向流写入一个字符,其原型是ofstream &put(char ch),使用也比较简单,如file1.put('c');就是向流写一个字符'c'。

    ②get()
  get()函数比较灵活,有3种常用的重载形式:

  一种就是和put()对应的形式:ifstream &get(char &ch);功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示从文件中读取一个字符,并把读取的字符保存在x中。

  另一种重载形式的原型是: int get();这种形式是从流中返回一个字符,如果到达文件尾,返回EOF,如x=file2.get();和上例功能是一样的。

  还有一种形式的原型是:ifstream &get(char *buf,int num,chardelim='\n');这种形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符,如果没使用delim 这个参数,将使用缺省值换行符'\n'。例如:

  file2.get(str1,127,'A');//从文件中读取字符到字符串str1,当遇到字符'A'或读取了127个字符时终止。

    ③读写数据块
  要读写二进制数据块,使用成员函数read()和write()成员函数,它们原型如下:

    read(unsigned char *buf,int num);
    write(const unsigned char *buf,int num);

  read()从文件中读取 num 个字符到 buf 指向的缓存中,如果在还未读入 num 个字符时就到了文件尾,可以用成员函数 intgcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件中,值得注意的是缓存的类型是unsigned char *,有时可能需要类型转换。


       

class RLETriples{
private:
	int num;
	int position;
	int length;

public:
        RLETriples();
	RLETriples(int n, int p, int l);
	int getNum();
	int getPosition();
	int getLength();
};

RLETriples::RLETriples(){
	num = 0;
	position = 0;
	length =0;
}

RLETriples::RLETriples(int n, int p, int l){
	num = n;
	position = p;
	length = l;
}


int main(){
        RLETriples  triples1(1, 0, 4);
        RLETriples  triples2(2, 4, 5);

        fstream fout, fin;

        fout.open("out", ios::app|ios::out|ios::binary);
        fout.write((char*)(&triples1), sizeof(triples1));
        fout.write((char*)(&triples2), sizeof(triples2));
        fout.close();

        RLETriples getTriples;
        fin.open("out", ios::in|ios::binary);
        fin.read((char*)(&getTriples),sizeof(getTriples));
        fin.close();
}


五、关于EOF/eof

      成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。原型是int eof(); 

      关于eof()函数的问题可以查看这里:http://blog.youkuaiyun.com/pear_zi/article/details/6917268

     

      另外,大写的EOF和小写的eof是不一样的。

      如上面说的,小写的eof是文件输入输出类中判断文件是否结束的函数。

      而大写的EOF,在C标准函式库中表示:文件结束符(End of File).他是一个宏定义的数值,为-1。这里要强调一点就是,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~255,不可能出现-1,因此可以用EOF作为文件结束标志。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值