zoukankan      html  css  js  c++  java
  • C++ ofstream和ifstream具体的方法和C语言file说明

     ofstream是从内存到硬盘,ifstream是从硬盘到内存,事实上所谓的流缓冲就是内存空间;

      在C++中,有一个stream这个类,全部的I/O都以这个“流”类为基础的,包含我们要认识的文件I/O,stream这个类有两个重要的运算符:

      1、插入器(<<)

      向流输出数据。比方说系统有一个默认的标准输出流(cout),普通情况下就是指的显示器,所以。cout<<"Write Stdout"<<' ';就表示把字符串"Write Stdout"和换行字符(' ')输出到标准输出流。

      2、析取器(>>)

      从流中输入数据。比方说系统有一个默认的标准输入流(cin),普通情况下就是指的键盘,所以。cin>>x;就表示从标准输入流中读取一个指定类型(即变量x的类型)的数据。

      在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的。所以,要用这样的方式操作文件。就必须增加头文件fstream.h。以下就把此类的文件操作过程一一道来。

      一、打开文件

      在fstream类中。有一个成员函数open(),就是用来打开文件的。其原型是:

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

      filename:  要打开的文件名称

      mode:    要打开文件的方式

      access:   打开文件的属性

      打开文件的方式在类ios(是全部流式I/O类的基类)中定义,经常使用的值例如以下:

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

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

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

    两种方式的差别见前文

      ios::in:    文件以输入方式打开(文件数据输入到内存)

      ios::out:   文件以输出方式打开(内存数据输出到文件)

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

      ios::noreplace:不覆盖文件。所以打开文件时假设文件存在失败

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

      能够用“或”把以上属性连接起来,如ios::out|ios::binary

      打开文件的属性取值是:

      0:普通文件。打开訪问

      1:仅仅读文件

      2:隐含文件

      4:系统文件

      能够用“或”或者“+”把以上属性连接起来,如3或1|2就是以仅仅读和隐含属性打开文件。

      比如:以二进制输入方式打开文件c:config.sys

      fstream file1;

      file1.open("c:\config.sys",ios::binary|ios::in,0);

      假设open函数仅仅有文件名称一个參数,则是以读/写普通文件打开,即:

      file1.open("c:\config.sys"); <=> file1.open("c:\config.sys",ios::in|ios::out,0);

      另外。fstream还有和open()一样的构造函数,对于上例。在定义的时侯就能够打开文件了:

      fstream file1("c:\config.sys");  特别提出的是。fstream有两个子类:ifstream(input file stream)和ofstream(outpu file stream)。ifstream默认以输入方式打开文件,而ofstream默认以输出方式打开文件。

      ifstream file2("c:\pdos.def");//以输入方式打开文件

      ofstream file3("c:\x.123");//以输出方式打开文件  所以,在实际应用中。依据须要的不同,选择不同的类来定义:假设想以输入方式打开,就用ifstream来定义;假设想以输出方式打开。就用ofstream来定义;假设想以输入/输出方式来打开,就用fstream来定义。

      二、关闭文件

      打开的文件使用完毕后一定要关闭。fstream提供了成员函数close()来完毕此操作,如:file1.close();就把file1相连的文件关闭。

      三、读写文件

      读写文件分为文本文件和二进制文件的读取。对于文本文件的读取比較简单,用插入器和析取器就能够了;而对于二进制的读取就要复杂些,下要就具体的介绍这两种方式

      1、文本文件的读写

      文本文件的读写非常easy:用插入器(<<)向文件输出;用析取器(>>)从文件输入。

    如果file1是以输入方式打开,file2以输出打开。示比例如以下:

      file2<<"I Love You";//向文件写入字符串"I Love You"

      int i;

      file1>>i;//从文件输入一个整数值。

      这样的方式另一种简单的格式化能力,比方能够指定输出为16进制等等。详细的格式有下面一些

      操纵符 功能 输入/输出

      dec 格式化为十进制数值数据 输入和输出

      endl 输出一个换行符并刷新此流 输出

      ends 输出一个空字符 输出

      hex 格式化为十六进制数值数据 输入和输出

      oct 格式化为八进制数值数据 输入和输出

      setpxecision(int p) 设置浮点数的精度位数 输出

      比方要把123当作十六进制输出:file1<<hex<<123;要把3.1415926以5位精度输出:file1<<setpxecision(5)<<3.1415926。

    < p="">

      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,char delim=' ');这样的形式把字符读入由 buf 指向的数组,直到读入了 num 个字符或遇到了由 delim 指定的字符。假设没使用 delim 这个參数。将使用缺省值换行符' '。

    比如:

      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 个字符时就到了文件尾,能够用成员函数 int gcount();来取得实际读取的字符数;而 write() 从buf 指向的缓存写 num 个字符到文件里。值得注意的是缓存的类型是 unsigned char *,有时可能须要类型转换。

      例:

      unsigned char str1[]="I Love You";

      int n[5];

      ifstream in("xxx.xxx");

      ofstream out("yyy.yyy");

      out.write(str1,strlen(str1));//把字符串str1所有写到yyy.yyy中

      in.read((unsigned char*)n,sizeof(n));//从xxx.xxx中读取指定个整数,注意类型转换

      in.close();out.close(); 四、检測EOF

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

      例:  if(in.eof()) ShowMessage("已经到达文件尾!");

      五、文件定位

      和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件里的位置;还有一个是写指针,它下次写操作的位置。每次运行输入或输出时,相应的指针自己主动变化。所以。C++的文件定位分为读位置和写位置的定位,相应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。

    它们最通用的形式例如以下:

      istream &seekg(streamoff offset,seek_dir origin);

      ostream &seekp(streamoff offset,seek_dir origin);

      streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置。是一个有下面值的枚举:

      ios::beg:  文件开头

      ios::cur:  文件当前位置

      ios::end:  文件结尾

      这两个函数一般用于二进制文件。由于文本文件会由于系统对字符的解释而可能与预想的值不同。

    例:

      file1.seekg(1234,ios::cur); //把文件的读指针从当前位置向后移1234个字节

      file2.seekp(1234,ios::beg); //把文件的写指针从文件开头向后移1234个字节

    语言文件系统称为流文件(Stream),正文流(正文文件),二进制流(二进制文件)

    缓冲与非缓冲文件
    顺序操作文件与随机操作文件
    顺序文件:读/写第K个数据块之前必须读/写第1至K-1个数据块。
    随机文件:可直接读/写第K个数据块;
    正文文件的操作通常是顺序文件。
    二进制文件的操作都是随机文件。


    一、文件操作的一般过程
    定义文件指针 FILE *
    打开文件 fopen
    对文件进行读写  

     

    二、系统已定义的与文件操作有关的数据结构全都在stdio.h中

    FILE 结构体

       FILE *fr,*fp,*fw;

    FILE* 指针作为文件句柄,是文件訪问的唯一标识,它由fopen函数创建。fopen打开文件成功。则返回一个有效的FILE*指针,否则返回空指针NULL


    标准文件指针

       FILE *stdin,*stdout,*stderr,
       stdin 指键盘输入
       stdout 指显示器
       stderr 指出错输出设备。也指显示器

    这些变量已成功初始化,可直接使用.
    三、经常使用操作函数

    fopen

    格式:FILE *fopen(文件名称字符串,打开方式串)

    例:FILE *fr; fr=fopen("c:\user\abc.txt","r");

    字符串操作:

    1)"r"或"rt":正文文件仅仅读方式打开。文件不存在,则打开失败(顺序读)"w"或"wt":正文文件仅仅写方式打开。若文件不存在,则建立文件;若文件存在,则删除文件内容,重建空文件(顺序写);(截取文件长度为0)

    2) "a"或"at":正文文件加入方式。

    文件不存在,则建立文件(顺序加入写)

    3) "r+"或"rt++":正文文件读写打开。文件不存在。则打开失败(顺序读/写、随机读/写,含改写与加入);

    4) "w+"或"w++":正文文件读写方式打开,文件不存在,则建立文件;否则截取文件长度为0(顺序读/写。随机读/写,对写入的内容能够读或改写或加入)

    5) ~b:正文文件→二进制文件
      顺序读→顺序/随机读(“rb”)

      eg:"r"或"rt"→"rb"
       顺序写("wb")
       顺序加入写("ab")
       顺...,随...,含...("rb+")
       顺...,加入("wb+")
       顺...,加入("ab+")

    使用fopen时,但凡含r字母的打开方式,一定要加推断。文件是否打开成功,否则程序不会报告错误,会执行下去。

    如:FILE *fr;
    fr=fopen("abc.txt","r");
    if(fr==NULL){
    printf("File not open! ");
    return;


    文件关闭

    fclose(FILE *fp)

    一般地,fclose(fp)与fopen应配对使用,特别是含有写方式的文件。若不关闭会造成文件数据丢失。

    fcloseall(void):关闭当前全部打开的文件。


    单字节的输入函数

    可适用于二进制与正文文件操作
    int fgetc(FILE *fp)
       int fputc(char ch.FILE *fp)

    fgetc的返回值都是正数(0~255)

    文件无可读字节则返回-1(EOF)

    正文文件与二进制文件读写的差别:
    正文文件读到13 10时,将自己主动跳过13,读出10并返回。正文文件写入10时,首先自己主动写入13再写入10.


    文件指针与文件指针操作函数

    文件指针是文件操作系统数据结构内部的一种数据指针,它用于标注文件当前读写位置,C语言中。文件指针以字节为单位,文件第一个字节位置号为0。若文件长度为N个字节,则最后一个字节的位置号为N-1,长度为N字节的文件有效读写范围为0~N-1。指针位置在此之外进行读/写操作,则失败;读写函数返回-1 (EOF)。

    C语言的文件指针採用long型值。

    运行文件读/写操作后,文件指针自己主动向后移动,指到新的待读/写位置。

    文件指针移动函数
    rewind(FILE *fp)
    文件指针重置为0
    fseek(FILE *fp,long off,int pos)
       从pos位置開始,移动off个字节。

    pos: 0 文件開始
          1 文件当前指针位置
          2 文件结尾(文件长度为N,则指针位置为N)

    例:fseek(fp,0l,0);←→rewind(fp)
    fseek(fp,-1L,2);
    fseek(fp,-2L,1);
    long ftell(FILE *fp)

    求当前指针位置

    例:求文件长度
    fseek(fp,OL,2);
    len=ftell(fp);
    则len为文件长度

    文件指针的特性:

    可在“负无穷”到“正无穷”随意移动。
    在0~N-1之外进行读操作,则读失败;读失败后,feof函数为真。
    从N位置開始写入。则为加入;
    从0~N位置之外開始写也可。其行为不必掌握,由于差点儿无用。
    不管不论什么方式,刚打开文件时,ftell函数返回值都是0,含a方式的文件,仅仅要一写(第一次写),文件指针自己主动移动到N位置处。
    int feof(FILE *fp)
    若文件读失败,则返回非0值,否则返回0值;仅用于读是否到文件尾。


    不论什么fseek操作使feof为假,即使文件指针在0~N-1之外。
    正文文件读/写函数
    fscanf(fp...)
       fprintf(fp...)

    当中。...与scanf和printf使用方法全然同样.
    scanf(...)←→fscanf(stdin...)
    printf(...)←→fprintf(stdout...)


    二进制文件读/写函数,即字节块函数
    int fread(char *buf,int size,int count,FILE *fp)
       int fwrite(char *buf,int&nbtp;size,int count,FILE *fp)
    从文件读出size x count个字节到内存块buf;从内存块buf写入size x count个字节到文件,返回实际读出/写入的字节数。

     

     

    一、文件里删除第K个记录:拷贝0~K-1,K+1~N条记录到一个暂时文件。删除源文件,将源文件改名为源文件。

    二、读/改写第K个记录:移动指针到第K个记录。用fread,fwrite改写。

    三、加入记录(略)

    四、插入记录

    复制暂时文件
    插入到K号记录之前:先将N-1写入N位置,N-2写入N-1,直到K写入K+1位置:用待插入记录改写K位置。(建立时用rb+方式打开)
    #include "tdio.h"
    void main()
    {FILE *fp;char ch1,ch2;long pos1,pos2,p;
    char fname[81];
    printf("Input C source filename:");
    gets(fname);
    fp=fopen(fname,"r+");
    if(!fp){printf("FILE not found . ); return;
    ch1=fgetc(fp);
    while(!feof(fp))
    {cha2=fgetc(fp);if(feof(fp)) break;
    if(ch1=='/'&&ch2=='*')
    {pos1=ftell(fp)-2;
    }
    if(ch1=='*'&&ch=='/')
    {pos2=ftell(fp)-1;
    fseek(fp,pos1,0);
    for(p=pos1;p<=pos2;p++) fputc(32,fp);
    fseek(fp,OL,1);
    }
    ch1=ch2;
    }
    fclose(fp); 


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    pat00-自测5. Shuffling Machine (20)
    Spiral Matrix
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Best Time to Buy and Sell Stock II
    4Sum
    3Sum Closest
    3Sum
    MySQL存储过程、函数和游标
    Word Ladder
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4724384.html
Copyright © 2011-2022 走看看