1.文件,文件与流,文件指针
2.文件的打开与关闭
3.文件的读写
文件的顺序读写:
(1)fgetc 和 fputc
(2)fgets 和 fputs
(3)fscanf 和 fprintf
(4)fread 和 fwrite
一.文件,文件与流,文件指针
1.文件的介绍:
(1)如果没有⽂件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失 了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久化的保存,我们可以使⽤ ⽂件
(2)磁盘(硬盘)上的⽂件是⽂件, 但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类 的)
程序文件:包扣源程序文件(后缀为.c),目标文件(windows环境后缀为.obj)和可执行程序(后缀为.exe)
数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或 者输出内容的⽂件
但根据数据的组织形式,数据文件又分为文本文件(.txt)和二进制文件(以二进制存储的文件),那一个数据又是如何在内存中存储呢:
(而在文件操作这一章,我们主要是将数据存入 .txt文件 或从 .txt文件里读取。)
(3)文件名:⽂件名包含3部分:文件路径+文件名主干+文件后缀
例如: c:\code\test.txt
2.文件与流:
(1)流:我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出 操作各不相同,为了⽅便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流 想象成流淌着字符的河。C程序针对⽂件、画面、键盘等的数据输⼊输出操作都是通过流操作的。 ⼀般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作。
(2)标准流:在C语言启动时默认打开的三个流:
stdin—标准输入流:在大多数环境中从键盘输入,scanf函数就从这里读取数据
stdout—标准输出流:⼤多数的环境中输出⾄显示器界⾯,printf函数就是将信息输出到标准输出 流中
stderr—标准错误流:⼤多数环境中输出到显⽰器界⾯
tdin、stdout、stderr三个流的类型是: FILE * ,通常称为⽂件指针
C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的
3.文件指针:
简而言之,C语言里FILE*文件指针用来维护流中的各种操作,在文件操作时就不可避免地使用到FILE*指针,由于文件指针指向该文件的信息区,那我们就可以通过文件指针变量简洁地找到文件以及与它相关的文件。
二.文件的打开与关闭
1.fopen(打开文件)与fciose(关闭文件):
当我们打开一个原本并不存在的文件时,VS会自动帮助我们在该项目路径底下创建一个文件
下面我们说说函数原型和文件的使用方式:
(1)fopen和fclose的函数原型:
filename表示文件名
stream表示文件指针
mode则是我接下来要说的文件的打开方式
(2)文件的打开方式:
例如我在文件里写一句话:
(注意,这里使用fopen等函数时,VS可能会默认其具有不安全性,因此需要在开头加上一句:#define _CRT_SECURE_NO_WARNINGS)
三.文件的读写
1.文件的顺序读写:
(其实我在上面已使用了fputs函数,但这里还是对fputs等一系列函数进行一下详细说明)
(1)fgetc (字符输入函数):
这两个函数全名叫做字符输入/出函数,适用于所有的输入/出流
同时这里也展示一下“w”的危害,他会清空我们原文件里的内容,使接下来的读取产生错误:
当然,读取所有字符也是可以的:
但这里我算过总字符的个数,所以写的12,但若读取的字符超过文件里的字符数,就会产生以下情况:
值得注意的是:
(1)当每次读取完成后,光标后往后移动一位。这时候我们在进行读取操作,就会读取到下一个字符。我们利用这个特性,用循环进行读取,达到读取字符串的功能。但是由于我们只有12个字符,所以打印出来后3个位置是错误信息。
(2)另外有一点需要注意,fgetc在遇到空格时会选择跳过。
接下来说说 fputc:
(2)fputc(字符输出函数):
以下为fputc的简单使用:
但有一个地方非常值得注意,就是在“w”的方式下,以下这串代码是无法实现的:
在“w”的打开方式下,fgetc无法读取的原因主要有两点:
(1)“w”是以写的方式打开文件
(2)写完之后光标移动到了写入字符的末尾,因此再往后读取是什么都读不到的
(3)fgets(文本行输入函数):
适用于所有输入流
char *str: 指向存储读取数据的字符数组的指针
int n: 需要读取的最大字符数,包括终止字符 \0
FILE *stream: 输入文件流的指针成功时,返回指向字符串的指针str
失败或者读取到文件结尾时返回NULL
在使用时这个函数时,可以理解为fgets作为一个文本(字符串)输入(输入到vs里的调试面板)函数,需要先创建一个数组来容纳从其他文件传来的字符串,再打印到面板上(同时,需要注意的是这个函数也是要在“r”只读情况下使用)
(这两种方式都行)
(4)fputs(文本行输出函数):
适用于所有输出流
const char *str:指向要写入的字符串的指针
FILE *stream:输出文件流的指针
成功时返回非负值(通常为0)
失败返回 EOF
这里直接在文件里写出了“WTF!”,同时也印证了“w”方式下写入会清空上一次的文件输入
(5)fscanf(格式化输入函数):
仅适用于文件输入流
fscanf函数用于从文件指针fp指向的文件中读取数据,根据format参数指定的格式化字符串来解析数据,并将解析的数据存储到后续的参数中,如果遇到文件结束或错误,返回EOF
(这个函数与scanf函数的用法非常非常相似,也就是意味着这个函数只要满足对应就可以实现多个参数的同时使用)
(6) sprintf (格式化输出函数):
仅适用于文件输出流
与printf一样,也可以传入多个参数并写入文件
(7)fread(二进制输入函数):
ptr:传入存放字符串的地址
size:每个数据单元的大小(以字节为单位)
nmemb:要读取的数据单元的数量
stream:文件指针,指向要读取的文件
返回值:fread函数返回成功读取的数据单元数量。如果返回值小于nmemb,则可能是遇到了文件结尾或发生了读取错误
(8)fwrite(二进制输出函数):
ptr:指向要写入数据的内存区块的指针,可以是数组、变量、结构体等。
size:表示每个数据块的字节数。
nmemb:表示要写入的块数。
stream:文件指针,指向要写入的文件。
返回值:fwrite函数返回成功写入的块数,即nmemb
综上,关于文件的顺序读写就分享到这,以下为顺序读写函数的汇总:
ok,到现在也讲了很多知识了,那接下来关于文件的随机读写,sprintf和sscanf,⽂件读取结束的判定以及缓冲区的介绍就留到文件操作(2)再做详细介绍吧。