11.文件

文件

C语言文件的基本概念

C语言将文件视为一个字符(字节)的序列——流(stream),即由一个一个字符(字节)的数据顺序组成。

根据数据的组成形式,可分为文本(text)文件和二进制文件。

ASCII文本文件每一个字节都存放一个ASCII代码,代表一个字符。

二进制文件是把内存中的数据按照在内存中的存储形式原样输出到磁盘上。

C语言没有提供对文件操作的语句,所有的文件操作都是利用C编译系统所提供的库函数来实现。

缓冲文件系统是指系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区,当从内存向磁盘输出数据时,先将数据输送到缓冲区中,缓冲区满后才写入磁盘。反之,如果从磁盘向内存读取数据,先将一批数据输入到缓冲区,然后再从缓冲区逐个将数据送到程序数据区(给程序变量)。缓冲区的大小由C编译系统确定。

非缓冲文件系统是指系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。

ANSCIC标准只采用缓冲文件系统。

文件指针

在缓冲文件系统中,打开文件时会返回一个指向FILE结构体的指针,就是文件指针。FILE结构体的定义在头文件<stdio.h>中,它含有用来处理文件的信息。

/* TURBO C中FILE的定义 */
typedef struct
{
  short level; /* 缓冲区满或者空的程度 */
  unsigned flags; /* 文件状态标识 */
  char fd; /* 文件描述符 */
  unsigned char hold; /* 如无缓冲区不读取字符 */
  short bsize; /* 缓冲区的大小 */
  unsigned char *buffer; /* 数据缓冲区的位置 */
  unsigned char *curp; /* 指针,当前的指向 */
  unsigned istemp; /* 临时文件指示器 */
  short token; /* 用于有效性检查 */
}FILE;

为了使用文件读写函数,首先应该定义一个文件指针变量,然后才可以使用文件函数,如:fopen(),fclose(),fgetc(),fputc(),fwrite(),fread()等。

/* 定义一个文件指针变量 */
FILE *fp;

文件的打开和关闭

对文件进行操作之前必须打开文件,文件使用结束之后应该关闭该文件。

  • fopen() - 打开文件

    /* fp=fopen(filename,mode) */
    FILE *fp;
    fp=fopen("test.txt","r");
    

    文件使用方式:

    mode含义
    r打开一个只供读取数据的文本文件。不可写入。
    rb打开一个只供读取数据的二进制文件。不可写入。
    w建立一个只供写入的文本文件,如果文件存在,则废弃当前内容。不可读取。
    wb建立一个只供写入的二进制文件,如果文件存在,则废弃当前内容。不可读取。
    a打开或建立一个在文件尾部追加数据的文本文件。
    ab打开或建立一个在文件尾部追加数据的二进制文件。
    r+打开一个即可读又可写的文本文件。
    rb+打开一个即可读又可写的二进制文件。
    w+建立一个即可读又可写的文本文件,如果文件存在,则废弃当前内容。
    wb+建立一个即可读又可写的二进制文件,如果文件存在,则废弃当前内容。
    a+打开或建立一个即可读又可在文件尾部追加数据的文本文件。
    ab+打开或建立一个即可读又可在文件尾部追加数据的二进制文件。

    在程序开始运行时,系统自动打开3个标准文件:标准输入、标准输出、标准错误输出。通常这三个文件都与终端联系。系统自定义了三个文件指针:stdin、stdout、stderr分别指向这三个文件。

  • fclose() - 关闭文件

    在使用完一个文件之后,应该立即关闭它,以防止它被误用。

    /* fclose(file_point) */
    fp=fopen("test.txt","r");
    /* ..... */
    fclose(fp);
    
    1. 由于每个文件都开辟了一个缓冲区,在写文件操作时,只有当缓冲区满了之后才向文件写入。如果缓冲区没满,当不关闭文件就结束一个程序时,就会丢失缓冲区中的数据。fclose()函数先将缓冲区的数据全部写入文件,然后再释放指针变量及缓存区。
    2. fclose()函数只有一个返回值,用来表示关闭是否成功。0表示成功,否则失败。ferror()函数可以用来测试fclose()函数的返回值。

文件的读写

文件打开之后,就可以进行读写操作了。C语言标准库提供了一整套文件读写函数,其函数原型声明在头文件<stdio.h>中。

  1. fput()和putc() -把一个字符写入文件

    fputc(ch,fp);
    putc(ch,fp);
    /* ch为要写入的字符 */
    /* 调用成功,函数返回值就是写入的字符。调用失败,则返回值为EOF。 */
    /* putchar函数是从fputc派生出来的:#define putchar(c) fputc(c,stdout) */
    
  2. fgetc()和get() -从文件中读取一个字符

    /* 从文件中读取一个字符,并赋给char ch */
    ch=fgetc(fp);
    /* 如果执行时遇到函数结束符,则函数返回一个文件结束标志EOF */
    
  3. fputs() -把一个字符串写入文件

    fputs(str,fp);
    /* str可以是数组名,字符指针变量或字符串常量 */
    /* 如果写入成功,返回0,否则,返回值为EOF */
    
  4. fgets() -从文件中读取一个字符串

    fgets(str,n,fp);
    /* str 是字符数组,n为要求得到的字符个数 */
    /* 因为字符串结束符''也占用一个字符,所以从文件中读入的字符个数为n-1个 */
    
  5. fwrite() -把指定字节数的数据块写入文件中

    fwrite(buf,size,count,fp);
    /* buf为要写入的数据在内存中的首地址;
    	 size为要写入到文件中的单个数据项的字节数;
    	 count为要写入的数据项的个数;
    */
    
  6. fread() -从文件中读取指定字节数的数据块

    fread(buf,size,count,fp);
    /* buf为读入的数据在内存中的首地址;
    	 size为要读取的单个数据项的字节数;
    	 count为要读取的单个数据项的个数;
    */
    /* 读取的数据块的总字节数为size*count个字节 */
    /* 函数调用成功,则返回值为读取的项数;如果出错,则返回0 */
    
  7. feof() -判断文件结束

    /* 如果文件结束,则返回1,否则返回0 */
    feof(fp);
    
  8. fscanf() -格式化读取函数

    fscanf(fp,[format_str],[var_addr_list]);
    
  9. fprinf() -格式化写入函数

    fprintf(fp,[format-str],[var_list]);
    

文件的定位

对于流式文件即可以进行顺序读写,也可以进行随机读写。在对文件进行随机读写时,有一个位置指针,完成随机读写的关键就是改变文件的的位置指针所指向的位置,即对文件进行定位。

  1. fseek() -改变文件的位置指针

    fseek(fp,offset,origin);
    /* orign为起始位置 */
    /* offset是以文件起始位置为基准值向前移动的字节数,为long int型数据 */
    

    orign的取值:

    宏名代表的数值代表的起始位置
    SEEK_SET0文件开始
    SEEK_CUR1文件当前位置
    SEEK_END2文件末尾
  2. ftell() -获取文件的当前位置

    /* 返回得到流式文件的当前位置,使用相对于文件开头的位移量来表示 */
    l=ftell(fp);
    /* l为一个long int型变量,如果结果为-1L,则表示出错 */
    
  3. rewind() -重置文件的位置指针(回到文件开头)

    /* 使文件的位置指针回到文件的开头 */
    rewind(fp);
    

文件的出错检测

  1. ferror() -检测文件读写是否出错

    /* 对于同一个文件,每一次调用输入输出函数,均产生一个新的ferror返回值 */
    /* 因此应该在调用一个输入输出函数后立即检查ferror函数值,否则信息或丢失 */
    ferror(fp); 
    /* 返回值为0表示未出错,非0则表示出错 */
    
  2. clearerr() -清楚文件的错误标志

    /* 只要出现错误标志,其错误值就会一直保留,直到调用clearerr()或者rewind() */
    clearerr(fp);
    
原文地址:https://www.cnblogs.com/xqisui/p/13849456.html