如果你是一个C语言初学者,那么你一定发现,目前我们的C语言程序只会在执行后自动退出,而不会保存数据及运行结果,那么如何才能保存数据呢?为了保存数据,我们可以用到文件操作。

目录

一.文件的打开和关闭-fopen()函数和fclose()函数

二.常见文件操作函数

三.文件位置指针相关操作函数

四.文件读取结束的判定

5.文件缓冲区


一.文件的打开和关闭-fopen()函数和fclose()函数

//打开文件
FILE * pf = fopen ( const char * filename, const char * mode );
//关闭文件
fclose ( pf);

1.FILE为C语言提供的文件类型,它是一个结构体类型,用于存放文件的相关信息。FILE*即为文件指针类型,通过该指针,我们可以对其相关联的文件进行一系列操作。

2.为了打开文件,文件名是不可缺少的。如果要打开当前目录下的文件,可只用输入文件名,否则应该输入文件的绝对路径,如:c:\code\test.txt

3.mode为打开文件的几种方式,常见的有"r"(只读),"w"(只写),"a"(文件末尾追加),"rb"(二进制件打开,只读),"wb"(二进制件打开,只读),"ab"(二进制件打开,追加)等。

用"r"方式打开文件,若文件不存在,则返回一个空指针表示错误。若用"w"或"a"打开文件,则若文件不存在,都会创建一个新文件,即使文件存在,写入时也会把原有内容先进行覆盖

4.在对文件进行相关操作后应该及时使用fclose函数进行关闭,以便及时释放资源

5.若fopen函数打开失败,则返回空指针,且设置全局变量 errno 来标识错误,因此打开文件后应该做必要的判断。对于flose函数,如果成功返回值为零。如果失败,则返回 EOF。

二.常见文件操作函数

1.字符输入函数-fgetc()

fgetc函数返回文件指针指向的字符,并使指针向下一个字符偏移。若想用此函数打印文件全部内容,可用while((ch=fgetc(pf))!=EOF)循环来控制,这是因为当指针指向文件结尾,函数返回值为-1

2.字符输出函数-fputc()

 由于要输出数据,故文件打开方式为"w",此时如图将字符c输出到了文件内

3.文本行输入函数-fgets()

 读取的最大字符数为(5-1)=4,这是因为字符串末尾会添加一个‘\0’作为字符串结束标志。该函数返回值为相同的 arr 参数。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针,因此同理可用while循环判断指针是否为NULL实现打印全部内容。

4.文本行输出函数-fputs()

                                        如图,能将字符串输入文件 

5.二进制输入-fread()

 首先需要了解,文本文件内容是以ASCII形式存储,而内存中,字符是以ASCII存储,而整形一般是以二进制进行存储,因此将字符‘4’以二进制输入(而非52),才得以输出字符‘4’。

函数返回值为成功读取的元素总数,如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。因此二进制文件的读取结束判断,可以判断返回值是否小于实际要读的个数

其参数为:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
  • ptr -- 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
  • size -- 这是要读取的每个元素的大小,以字节为单位。
  • nmemb -- 这是元素的个数,每个元素的大小为 size 字节。
  • stream -- 这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流

6.二进制输出-fwrite()

如图,参数同上,只不过变为输出,将数据内容输出到文件中。此处输出内容为字符,否则在文本文件显示中会产生乱码,如:

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

7.格式化输入函数-fscanf()

如图,将文件内容以格式化输入的方式赋值给变量,再进行打印

顺便一提sscanf函数,它是将字符串内容以格式化方式输出,其第一个参数是指向字符数组的指针 

8.格式化输出函数-fprintf()

如图,基本与printf函数参数相同,只是多了一个文件类型指针的参数,能以格式化输出的方式将内容输出到文件内。

顺便提一下sprintf()函数。fprintf函数能将数据内容向所有输出流输出,而sprintf函数便是将数据内容保存为字符串,其第一个参数是指向字符数组的指针

三.文件位置指针相关操作函数

我们需要知道,文件内部的位置指针用以指示文件内部的当前读写位置,每读写一次,该指针均向后移动

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

如图,以"r"的方式打开文件,位置指针初始时在文首,偏移量为0,而每进行一次字符读写,偏移量便加一。 ftell函数能反映当前文件位置指针的位置

2.rewind()函数-让文件指针的位置回到文件的起始位置

如图,使用rewind函数后,偏移量归零。

3.fseek()函数-根据文件指针的位置和偏移量来定位文件指针。

其第一个参数为文件类型指针

第二个参数为指定偏移量,若为负值则位置指针向前偏移

第三个参数为指定初始偏移位置,有:SEEK_SET为文件开头位置,SEEK——CUR为当前位置指针的位置,SEEK_END则为文件结尾位置

如图指定初始偏移位置为文件开头SEEK_SET,偏移量为1,打印后位置指针相对于起始位置偏移量便是1

四.文件读取结束的判定

1.ferror()函数-判断是否由于发生错误而结束读取

若读取错误而结束,该函数返回一个非零值,否则返回一个零值。

如图以"w"(只写)方式进行读取操作,显然由于错误而结束读取文件。

2.feof函数-判断是否遇到文件结束而结束读取

若遇到文件结束标志而结束读取,该函数返回一个非零值,否则返回零。

如图以"r"方式正常读取,用while循环一直读取知道fgetc函数返回值为EOF,即遇到文件结束标志

需注意,文件结束并非指位置指针置于文件末尾,feof必须在读取到EOF标志后才返回非零值

如图若用fseek函数将位置指针移动到末尾,此时feof函数对应内容并未打印,这是因为EOF还尚未被读取,相关内容附上原文链接:http://t.csdn.cn/Z6Y4B,原文:关于C语言中feof的使用

5.文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序 中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装 满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓 冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。

#include <stdio.h>
#include <windows.h>
//VS2013 WIN10环境测试
int main()
{
 FILE*pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//先将代码放在输出缓冲区
 printf("此时打开文件,没有内容\n");
 Sleep(10000);//程序睡眠10秒
 printf("刷新缓冲区\n");
 fflush(pf);//刷新缓冲区时,将输出缓冲区的数据写到文件(磁盘)
 printf("再次打开test.txt文件,文件有内容了\n");
 Sleep(10000);
 fclose(pf);
 //注:fclose在关闭文件的时候,也会刷新缓冲区
 pf = NULL;
 return 0;
}

C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件,以便将缓冲区数据写到磁盘文件内,如果不做,可能导致读写文件的问题。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐