[C/C++]C语言中对文件的操作方法

7 篇文章 0 订阅
3 篇文章 0 订阅

C语言中有许多对文件的操作方法,

首先我们要明确一些概念,

在程序设计中,我们一般谈的文件有两种:程序文件、数据文件。

文件名:一个文件要有一个唯一的文件标识,以便用户识别和引用。文件名包含3部分:文件路径+文件名主干+文件后缀

文件类型:根据数据的组织形式,数据文件被称为文本文件或者二进制文件。(存储同样大小的数据,二进制文件大小小于文本文件原因如图)

文件缓冲区:ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。。缓冲区的大小根据C编译系统决定的。

文件指针:在C语言中用一个指针变量指向一个文件,这个指针称为文件指针。通过文件指针就可对它所指的文件进行各种操作。文件的名字,文件状态及文件当前的位置等。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE.如stdio.h 头文件中有以下的文件类型申明:

struct _iobuf {
    char *_ptr;
    int _cnt;
    char *_base;
    int _flag;
    int _file;
    int _charbuf;
    int _bufsiz;
    char *_tmpfname;
    };
typedef struct _iobuf FILE;

可以通过一个FILE的指针来维护这个FILE结构的变量。创建一个FILE*的指针变量:

FILE* pf;//文件指针变量

定义pf是一个指向FILE类型数据的指针变量。通过文件指针变量能够找到与它关联的文件。

 下面介绍一些文件的基本操作函数:

1.文件的打开和关闭

    文件在读写之前先打开文件,在使用结束后关闭文件。

     ANSIC 规定使用fopen函数打开文件,返回一个FILE*的指针变量指向该文件。fclose来关闭文件。

FILE * fopen ( const char * filename, const char * mode );
int fclose ( FILE * stream );

    FILE *fopen(const char *filename, const char *mode);其功能是使用给定的模式 mode 打开 filename 所指向的文件。文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在 error 中。

    int fclose(FILE *stream)关闭流 stream。刷新所有的缓冲区。返回值:如果流成功关闭,fclose 返回 0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)

    上边提到的打开方式如下:

     文件使用方式含义如果指定文件不存在
    “r”(只读)   :为了输入数据,打开一个已经存在的文本。如果文件不存在则文件出错。
    “w”(只写)  : 为了输出数据,打开一个文本文件。如果文件不存在则建立一个新的文件。
    “a”(追加)   :向文本文件尾添加数据。如果文件不存在则出错。
    “rb”(只读)  : 为了输入数据,打开一个二进制文件。如果文件不存在则出错。
    “wb”(只写) : 为了输出数据,打开一个二进制文件。如果文件不存在则建立一个新的文件。
    “ab”(追加)  : 向一个二进制文件尾添加数据。如果文件不存在则出错。
    “r+”(读写)   : 为了读和写,打开一个文本文件。如果文件不存在则出错。
    “w+”(读写) : 为了读和写,建议一个新的文件。如果文件不存在则建立一个新的文件。
    “a+”(读写)  : 打开一个文件,在文件尾进行读写。如果文件不存在则建立一个新的文件。
    “rb+”(读写) :为了读和写打开一个二进制文件。如果文件不存在则出错。
    “wb+”(读写): 为了读和写,新建一个新的二进制文件。如果文件不存在则建立一个新的文件。
    “ab+”(读写): 打开一个二进制文件,在文件尾进行读和。如果文件不存在则写建立一个新的文件。

     如:

#include <stdio.h>
int main ()
{
    FILE * pFile;
    pFile = fopen ("myfile.txt","w");
    if (pFile!=NULL)
    {
        fputs ("fopen example",pFile);
        fclose (pFile);
    }
    return 0;
}

    打开后要判断 pfile指针的有效性。

2.文件的顺序读写

   介绍一些输入输出函数。

   (1) 字符输入函数int fgetc(FILE *stream) 从指定的流 stream 获取下一个字符(一个无符号字符),并把位置标识符往前移动。stream 是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。适用于:所有输入流。

   (2)字符输出函数 int fputc(int char, FILE *stream) 把参数 char 指定的字符(一个无符号字符)写入到指定的流 stream 中,并把位置标识符往前移动。char 是要被写入的字符。该字符以其对应的 int 值进行传递。stream是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符的流。如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。适用于:所有输入流。

   (3)文本行输入函数char *fgets(char *str, int n, FILE *stream) 从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。str 是指向一个字符数组的指针,该数组存储了要读取的字符串。n 是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。stream是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。如果成功,该函数返回相同的 str 参数。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。如果发生错误,返回一个空指针。适用于:所有输入流。

   (4)文本行输出函数 int fputs(const char *str, FILE *stream) 把字符串写入到指定的流 stream 中,但不包括空字符。str是一个数组,包含了要写入的以空字符终止的字符序列。stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流。该函数返回一个非负值,如果发生错误则返回 EOF。适用于:所有输入流。

   (5) 格式化输入函数int fputs(const char *str, FILE *stream) 把字符串写入到指定的流 stream 中,但不包括空字符。str是一个数组,包含了要写入的以空字符终止的字符序列。stream是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流。该函数返回一个非负值,如果发生错误则返回 EOF。适用于:所有输入流。

   (6)格式化输出函数int fprintf(FILE *stream, const char *format, ...) 发送格式化输出到流 stream 中。stream是指向 FILE 对象的指针,该 FILE 对象标识了流。format是 C 字符串,包含了要被写入到流 stream 中的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。适用于:所有输入流。

   (7) 二进制输入size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 从给定流 stream 读取数据到 ptr 所指向的数组中。ptr 是指向带有最小尺寸 size*nmemb 字节的内存块的指针。size是要读取的每个元素的大小,以字节为单位。nmemb是元素的个数,每个元素的大小为 size 字节。stream是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。适用于:文件。

   (8)二进制输出size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 把 ptr 所指向的数组中的数据写入到给定流 stream 中。ptr是指向要被写入的元素数组的指针。size 是要被写入的每个元素的大小,以字节为单位.nmemb 是元素的个数,每个元素的大小为 size 字节。stream 是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误。适用于:文件。

3.文件的随机读写

   (1) fseek根据文件指针的位置和偏移量来定位文件指针。

int fseek ( FILE * stream, long int offset, int origin );

    如果成功,则该函数返回零,否则返回非零值。stream是指向 FILE 对象的指针,该 FILE 对象标识了流。offset 是相对 whence 的偏移量,以字节为单位。whence 是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:

常量描述
SEEK_SET文件的开头
SEEK_CUR文件指针的当前位置
SEEK_END文件的末尾

   (2)ftell返回文件指针相对于起始位置的偏移量.

long int ftell ( FILE * stream );

      stream是指向 FILE 对象的指针,该 FILE 对象标识了流。该函数返回位置标识符的当前值。如果发生错误,则返回 -1L,全局变量 errno 被设置为一个正值。

   (3)rewind让文件指针的位置回到文件的起始位置

void rewind(FILE *stream)

          stream 是指向 FILE 对象的指针,该 FILE 对象标识了流。

4.文件结束判定

   int feof(FILE *stream) 测试给定流 stream 的文件结束标识符。

   在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

 (1) 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)例如:fgetc判断是否为EOF.fgets判断返回值是否为NULL。

 (2) 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。例如:fread判断返回值是否小于实际要读的个数。

文本文件的例子:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    int c; 
    FILE* fp = fopen("test.txt", "r");
    if(!fp) 
        {
            perror("File opening failed");
            return EXIT_FAILURE;
        }
    while ((c = fgetc(fp)) != EOF) 
        {
            putchar(c);
        }
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
    fclose(fp);
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值