《C语言文件操作》

目录

1. 文本数据和二进制

        1.1 文本数据

        1.2 二进制数据

        1.3文本文件和二进制文件

2. 文件的打开和关闭

        2.1 文件指针

        2.2 打开文件

        2.3 关闭文件

        2.4 注意事项:

3. 文本文件的读写

        3.1 向文件中写入数据

        3.2 从文件中读取数据

        3.3 注意事项

4. 二进制文件的读写

        4.1 向文件中写入数据

        4.2 从文件中读取数据

5.文件定位

        5.1ftell函数

        5.2rewind函数

        5.3fseek函数

6.文件缓冲区

7.标准输入、标准输出和标准错误


1. 文本数据和二进制

1.1 文本数据

        文本数据由字符串组成,存放了每个字符的 ASCII 码值,每个字符占一个字节,每个字节存放一个字符

        比如数字 123,如果用文本格式存放,数据内容是'1'、'2'、'3' 三个字符,占三个字节

 表格形式:

1.2 二进制数据

        二进制数据是字节序列,数字123的二进制表示是01111011,如果用二进制格式形式存储,char、short、int、long都可以存储123

1.3文本文件和二进制文件

  1. 按文本格式存放数据的文件称为文本文件或ASCII文件,文件可以用vi和记事本打开,看到的都是ASCII字符

  2. 按二进制格式存放数据的文件称为二进制文件,如果用 vi/vim 打开二进制文件,看到的是乱码

2. 文件的打开和关闭

        对文件进行操作之前必须先“打开”文件,操作(读和写)完成后,再“关闭”文件

2.1 文件指针

  1. 操作文件的时候,C语言为文件分配一个信息区,该信息区包含文件描述信息缓冲区位置缓冲区大小文件读写到的位置等基本信息,这些信息用一个结构体来存放(struct _IO_FILE),FILE结构体和对文件操作的库函数在 stdio.h 头文件中声明的

  2. 打开文件的时候,fopen 函数中会动态分配一个FILE结构体大小的内存空间,并把FILE结构体内存的地址作为函数的返回值,程序中用FILE结构体指针存放这个地址

  3. 关闭文件的时候,fclose 函数除了关闭文件,还会释放FILE结构体占用的内存空间

  4. FILE结构体指针习惯称为文件指针

2.2 打开文件

        C语言提供的库函数 fopen 来创建一个新的文件或者打开一个已存的文件,调用fopen函数成功后,返回一个文件指针( FILE *)

函数原型如下:

FILE fopen( const char filename, const char * mode );
  1. 参数 filename 是字符串,表示需要打开的文件名,可以包含目录名,如果不包含路径就表示程序运行的当前目录

  2. 参数 mode 也是字符串,表示打开文件的方式(模式),打开方式有很多种,我们来看一个表格

        不用去死记硬背 read简写r、write简写w、append简写a罢了

        有的说打开文本文件的方式要用"rt"、"wt"、"at"、"rt+"、"wt+"、"at+","t"是text的简写,"t"可以省略不写

        有的说打开二进制文件的方式要用"rb"、"wb"、"ab"、"rb+"、"wb+"、"ab+","b"是binary的简写

2.3 关闭文件

        fclose 库函数用于关闭文件

函数原型如下:

int fclose(FILE *fp); //fp为fopen函数返回的文件指针
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
int main() 
{ 
    FILE *fp = 0; //定义文件指针fp 
    // 以只读的方式打开文件 
    if ((fp = fopen("/root/cyy1/test83.c","r")) ==0)
    { 
        printf("文件打开失败\n"); 
        return -1; 
    } 
    fclose(fp); 
    return 0; 
}

2.4 注意事项:

1.调用 fopen 打开文件的时候,一定要判断返回值,如果文件不存在、或没有权限、或磁盘空间满了,都有可能造成打开文件失败

2.文件指针是调用 fopen 的时候,系统动态分配了内存空间,函数返回或程序退出之前,必须用 fclose 关闭文件指针,释放内存,否则后果严重

3.如果文件指针是空指针或野指针,用 fclose 关闭它相当于操作空指针或野指针,后果严重

3. 文本文件的读写

3.1 向文件中写入数据

        C语言向文件中写入数据库函数有 fputc 、fputs、fprintf。

fprintf函数的声明如下:

int fprintf(FILE *fp, const char *format, ...);

        fprintf函数的用法与printf相同,只是多了第一个参数文件指针罢了,表示把数据输出到文件

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
int main() 
{ 
    FILE *fp = 0; //定义文件指针fp 
    // 以只写的方式打开文件 
    if ( (fp=fopen("/root/cyy1/test84.txt","w")) ==0 ) 
    { 
        printf("文件打开失败\n"); 
        return -1; 
    } 
    int i = 0; 
    for (i = 0;i < 3 ;i++) 
    { 
        fprintf(fp,"这是第%d名同学\n",i+1); 
    } 
    fclose(fp); 
    return 0; 
}

        可以看到 /root/cyy1/test84.txt 中有3行记录,程序 test84.c 不管执行多少次,记录都是3行,因为文件打开的方式是 "w",每次打开文件的时候都会清空原文件中的记录

3.2 从文件中读取数据

        从文件中读取数据的库函数有 fgetc 、fgets、fscanf。

fgets函数的原型如下:

char *fgets(char *buf, int size, FILE *fp);

fgets的功能是从文件中读取一行

1.参数 buf 是一个字符串,用于保存从文件中读到的数据

2.参数 size 是打算读取内容的长度

3.参数 fp 是待读取文件的文件指针

4.如果文件中将要读取的这一行的内容的长度小于size,fgets函数就读取一行,如果这一行的内容大于等于size,fgets函数就读取size-1字节的内容

5.调用fgets函数如果成功的读取到内容,函数返回buf,如果读取错误或文件已结束,返回空,即0。如果fgets返回空,可以认为是文件结束而不是发生了错误,因为发生错误的情况极少出现

3.3 注意事项

1.在读取到 size-1 个字符之前如果出现了换行,或者读到了文件末尾,则读取结束

2.不管 size 的值多大,fgets函只读取一行数据,不能跨行

3.可以将 size 的值设置地足够大,确保每次都能读取到一行完整的数据

4. 二进制文件的读写

  1. 二进制文件没有行的概念,没有字符串的概念

  2. 我们把内存中的数据结构直接写入二进制文件,读取的时候,也是从文件中读取数据结构的大小一块数据,直接保存到数据结构中。这里所说的数据结构不只是结构体,是任意数据类型

4.1 向文件中写入数据

        fwrite函数用来向文件中写入数据块

原型为:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

参数:

  1. ptr -- 这是指向要被写入的元素数组的指针

  2. size -- 这是要被写入的每个元素的大小,以字节为单位

  3. nmemb -- 这是元素的个数,每个元素的大小为 size 字节

  4. stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流

返回值:

        如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误

4.2 从文件中读取数据

        fread函数用来从文件中读取数据块

原型为:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

参数

1.ptr -- 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针

2.size -- 这是要读取的每个元素的大小,以字节为单位

3.nmemb -- 这是元素的个数,每个元素的大小为 size 字节

4.stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流

返回值

        调用fread函数如果成功的读取到内容,函数返回读取到的内容的字节数,如果读取错误或文件已结束,返回空,即0。如果fread返回空,可以认为是文件结束而不是发生了错误

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
struct Student 
{ 
    char name[51]; 
    int age; 
    int height; 
}; 
int main() 
{ 
    FILE *fp = 0; //定义文件指针fp 
    struct Student stu; // 以只读的方式打开文件 
    if ( (fp=fopen("/root/cyy1/test86.txt","rb")) ==0 ) 
    { 
        printf("文件打开失败\n"); 
        return -1; 
    } 
while (1) 
{ 
    if ( (fread(&stu,sizeof(stu),1,fp)) == 0) 
    {
        break; 
    }
    printf("姓名:%s 年龄:%d 身高:%d\n",stu.name,stu.age,stu.height); 
} 
    fclose(fp); 
    return 0; 
}

5.文件定位

        1.在文件内部有一个位置指针,用来指向文件当前读写的位置。在文件打开时,如果打开方式是r和w,位置指针指向文件的第一个字节,如果打开方式是a,位置指针指向文件的尾部。每当从文件里读取n个字节或文件里写入n个字节后,位置指针也会向后移动n个字节

        2.文件位置指针与C语言中的指针不是一回事。位置指针仅仅是一个标志,表示文件读写到的位置,不是变量的地址。文件每读写一次,位置指针就会移动一次,它不需要您在程序中定义和赋值,而是由系统自动设置

        3.C语言提供了 ftell 、rewind 和 fseek 三个库函数来实现文件定位功能

 5.1ftell函数

        ftell函数用来返回当前文件位置指针的值,这个值是当前位置相对于文件开始位置的字节数

声明:

long int ftell(FILE *stream)

5.2rewind函数

        rewind函数用来将位置指针移动到文件开头

声明:

void rewind ( FILE *fp );

5.3fseek函数

        fseek函数用来将位置指针移动到任意位置

声明:

int fseek(FILE *stream, long int offset, int whence)

参数

  1. stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流

  2. offset -- 这是相对 whence 的偏移量,以字节为单位

  3. whence -- 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一

返回值

如果成功,则该函数返回零,否则返回非零值

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
int main() 
{ 
    FILE *fp = 0; //定义文件指针fp 
    // 以只读的方式打开文件 
    if ( (fp=fopen("/root/cyy1/book1.txt","w+")) ==0 ) 
    { 
        printf("文件打开失败\n"); 
        return -1; 
    } 
    fprintf(fp,"hello world\n"); 
    fseek(fp,6,SEEK_SET);//光标在第二行的第6个字节处,下一行代码写入从第二行第七个字节位置开始写    入 
    fprintf(fp,"xiaoqiu\n"); 
    fclose(fp); 
    return 0; 
}

        最初程序创建文件和写入 hello world,但是之后我们在第6个位置重置了写指针,并使用 fprintf 语句来重写文件,所以 book1.txt 里面的内容是 hello xiaoqiu

6.文件缓冲区

        在操作系统中,存在一个内存缓冲区,当调用fprintf、fwrite等函数往文件写入数据的时候,数据并不会立即写入磁盘文件,而是先写入缓冲区,等缓冲区的数据满了之后才写入文件。还有一种情况就是程序调用了 fclose 时也会把缓冲区的数据写入文件

        如果想把缓冲区的数据立即写入文件,可以调用 fflush 库函数

声明如下:

int fflush(FILE *fp);

        函数的参数只有一个,即文件指针,返回0成功,其它失败

7.标准输入、标准输出和标准错误

        Linux操作系统为每个程序默认打开三个文件,即标准输入stdin、标准输出stdout和标准错误

        输出stderr,其中0就是stdin,表示输入流,指从键盘输入,1代表stdout,2代表stderr

例如:

printf("Hello xiaoqiu.\n");

等同于

fprintf(stdout,"Hello xiaoqiu.\n");

感谢你的阅读,希望对你有所帮助~

欢迎批评指正,共同进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿!=程序员

感谢来过,感谢有你!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值