600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > C语言 文件 文件操作 文件相关函数

C语言 文件 文件操作 文件相关函数

时间:2018-09-16 07:48:59

相关推荐

C语言 文件 文件操作 文件相关函数

目录

1、概念

2、文件路径

2.1、绝对路径

2.2、相对路径

3、文件分类

3.1、文本文件(ASCII文件)

3.2、二进制文件

4、缓存

4.1、缓存

4.2、文件缓冲区

5、文件操作函数

5.1、文件打开

5.2、文件数据写入

5.3、文件数据读取

5.4、文件关闭

6、拷贝文件小练习

6.1、拷贝文本文件

6.2、歌曲拷贝

7、文件相关函数

7.1、文件相关知识

7.2、文件光标移动函数 fseek(),文件字节数统计函数 ftell()

7.3、getc(),putc()

扩充:

扩充:

7.3、fgets(),fputs()

7.4、 fscanf()、fprintf()

8、总结

1、概念

文件:存储在外部介质上数据的集合。

●我们用 "" 表示数据从源端到目的端(终端)的流动。文件从外存被调入内存的过程就产生了输入流,从内存往外存中保存的过程就产生了输出流。

文件光标:当我们打开一个文件时,鼠标在文件中点击一下,就会出现一个文件光标在跳动。这代表了我们可以在当前位置对文件进行编辑或者读取。文件光标位置可以通过函数fseek()指定,在下面文件相关函数中介绍。

文件结束标记EOF:在文件的末尾会有一个标记字符EOF来表示文件数据就那么多,后面没有了。EOF是一个宏,其值为-1。

2、文件路径

通过文件路径,我们可以知道文件在计算机外存中的存储位置,从而找到该文件,再进行目标操作。

2.1、绝对路径

绝对路径就是从根目录开始的完整的文件路径。Windows上根目录有C盘、D盘等等,Linux的根目录只有一个:/。

所以,在Windows电脑上一个绝对路径可以是 C:\Users\861\Pictures\画图\输入输出流.png。

但是,如果将这段路径保存为字符串时,就需要将单个反斜杠换成双反斜杠。因为单个反斜杠是转义字符的标志,双斜杠在字符串中才表示一个斜杠:"C:\\Users\\861\\Pictures\\画图\\输入输出流.png"。

也可以用正斜杠来代替反斜杠:"C:/Users/861/Pictures/画图/输入输出流.png"。

2.2、相对路径

相对路径就是在当前所在的目录(文件夹)下,文件相对于本文件夹的路径。所以,相对路径的前提是目标文件在本文件夹(或本文件夹的子文件夹)中

对于Pictures文件夹,输入输出流.png文件的绝对路径就是"画图/输入输出流.png"。

3、文件分类

3.1、文本文件(ASCII文件)

文本文件的后缀名为 .text、.cpp等,存储方式为字符串。也就是对于数字123,其在文本文件中以字符形式存储为'1','2',‘3’,大小为三字节。

3.2、二进制文件

多媒体文件全都存储为二进制文件(0101二进制机器码形式),后缀名为:.ppt、.mp3、.jng等。对于数字123,其在二进制文件中的存储形式为0111 1011,大小为1字节。

4、缓存

4.1、缓存

缓存是数据交换的缓冲区。

当CPU要读取数据时,先在缓存中查找数据,如果找到了数据,就直接使用;如果没找到,就去内存中找;如果内存中还没有就去外存中找。如果同一数据被多次从外存调入内存使用,系统就将该数据保存在缓存中,提高效率。

4.2、文件缓冲区

数据在存入文件,或我们通过scanf()对变量进行赋值时,不是一个数据一个数据进行操作的,而是先将数据保存在缓冲区,等数据数量达到上限,或输入结束,再将所有数据按顺序进行保存或赋值。

●ANSI C标准采用“缓冲文件系统”处理数据文件。

●文件系统:组织,管理文件的方法和数据结构。

●“缓冲文件系统”:系统自动地在内存中为每一个正在使用的文件开辟一个文件缓冲区。如果要将内存中的数据保存到外存的文件中,就将所有数据先输入到输出文件缓冲区中等缓冲区被装满,或操作完成时,再将所有缓冲区的数据按顺序存储到外存中;然后对缓冲区进行刷新,等待下次操作。将文件数据调入内存中时原理相同。

缓冲区未装满之前,会进行等待,等到装满、操作完成或程序结束时,将数据进行向外存保存。目的是为了减少I/O调用,减少时间的浪费

5、文件操作函数

5.1、文件打开

文件打开函数是fopen(),使用形式为:FILE* fp = fopen(" 文件路径.后缀名","读写模式");

●fopen()的返回值为文件类型的结构体指针FILE* ,结构体的成员变量是文件的各种信息,指针指向了该文件。

●文件路径可以是绝对路径,也可以是相对路径,但要注意使用 "\\"或"/"。

●文件的读写模式分两大类,一种是针对文本文件,一种是针对二进制文件。其原理都相同,只不过二进制文件的读写模式在文本文件的读写模式后加上字母b。

以只读模式打开,就只能对文件数据进行读取,不能添加或修改;以只写模式打开,就只能对文件进行数据写入,不能读取。所以,为了方便操作,一般选择r+、w+或a+模式打开文件。

5.2、文件数据写入

文件数据写入函数为fwrite(),使用形式为:fwrite(buff,sizeof(数据类型),count,fp); 意为将buff字符串或字符数组中的count个数据写入到fp指针指向的文件中去。

●fwrite()的返回值为count,是写入到文件中的数据个数;

●sizeof(数据类型):是我们要写入文件中的数据的单个数据字节大小。

●count:这一次操作要向文件写入的数据个数;如果buff中的数据少于count,则系统会硬从缓冲区中读取够count个数据,写入到文件中。所以,count的大小应为buff数组中有效数据个数

●fp:指向要写入数据的文件的指针。

5.3、文件数据读取

文件数据读取函数是fread(),其使用形式为fread(buff,sizeof(char),count,fp);意为将fp指向的文件中最多count个数据读取到buff字符数组中。数据的读取是从文件数据首部开始,若文件数据量大于count,文件光标移动到count位置,下一次的读取从count位置开始。

●fread()返回值是成功从文件中读取到的实际数据个数,若fp指向文件的数据数量小于count,就只读取实际的数量。

●sizeof(char):单个数据大小。

●count:一次性想从fp指向的文件中读取的数据个数,注意不能超出buff的容量。

●fp:指向要读取数据的文件的指针。

5.4、文件关闭

文件关闭函数为fclose(),使用形式为fclose(fp);

文件被打开使用完之后,就需要关闭。正如上述所言,文件被使用时,系统会给文件开辟一块文件缓冲区,并且还会占据其他资源;如果只打开文件,而不关闭,必然会导致系统资源被浪费。

6、拷贝文件小练习

6.1、拷贝文本文件

对于一个文件"hello.text",其内容为"hello,world!",将其内容拷贝到一个新文件"newhello.text"中。

//以只读模式,打开hello.text文件,以fp1指向//以r模式打开文件,只能对文件进行数据读取,//若文件不存在,会返回NULL值FILE* fp1 = fopen("C:\\Users\\86187\\Documents\\hello.txt","r");assert(fp != NULL); //若打开失败,就中断程序//以可读可写w+模式,打开newhello.text文件,以fp2指向//系统中没有newhello.text,程序会自动创建文件FILE* fp2 = fopen("C:\\Users\\86187\\Documents\\newhello.txt", "w+");assert(fn != NULL);//用来保存一次性读取到的数据,数组大小可以更大//也可以用一个char型变量来保存,//一次只读取一个字符,就比较慢char buff[256]={0}; int count = 0;//用count记录每次成功读取到的数据量//若count==0,意味着文件数据被读取完了while (count = fread(buff, sizeof(char), 255, fp)) {//将buff中读取到的数据写入新文件//读取到count个,就写入count个//否则系统会强转从缓存区读取够你指定的数量//就会读取到其他未知数据fwrite(buff, sizeof(char), count, fn);//将buff中数据清空,防止影响下次写入memset(buff, 0, 256);}fclose(fp); //关闭文件fclose(fn);

若执行成功,就会在指定路径下找到新拷贝的文件。

6.2、歌曲拷贝

在音乐软件中,下载一首普通歌曲。确认路径,然后以二进制文件形式打开。虽然二进制文件与文本文件对于数据的存储方式有所不同。如123:以文本文件存储为'1','2','3';以二进制文件存储为 123的二进制形式:0111 1011。但是,其最根本的形式还是二进制0101...机器码,所以我们直接按字节大小来读取。

一个char型数据容量为1字节,一个256个格子的字符数组能保存256个字节的数据。我们使用数组来保存读取到的字节数据,设置一次性读取的最大数据量为255,也可以是256、254......。count为实际读取到的数据字节数,根据实际字节数,将数据写入新文件。

//以二进制读模式打开歌曲FILE* fp1 = fopen("D:/KuGou/EXO - 咆哮 (Chinese ver.).mp3", "rb");//以二进制读写模式打开新歌曲文件//没有文件,自动创建FILE* fp2 = fopen("D:/KuGou/NewSong.mp3", "wb+");char buff[256] = { 0 };int count = 0;while (count = fread(buff, sizeof(char), 255, fp1)) {fwrite(buff, sizeof(char), count, fp2);//清空buff数组,防止影响下次写入数据memset(buff, 0, count);}fclose(fp1);fclose(fp2);

若歌曲拷贝成功,就可以进行播放。新歌名为NewSong,歌手未知,但其他数据全部拷贝过来了。

7、文件相关函数

7.1、文件相关知识

1、我们先了解一下关于文件头部,光标当前位置和文件尾部的宏定义:

SEEK_SET:文件头部。数值:0

SEEK_CUR:文件光标当前位置。数值:1

SEEK_END:文件尾部。数值:2

2、标准输入stdin、标准输出stdout、标准错误stderr

在程序运行的时候,系统会默认开启三个输入输出流,stdin默认指向键盘,stdout和stderr默认指向屏幕,也可以重定向输出到文件中。这仨个流分布完成数据的传输:stdin将输入数据传输到指定位置,stdout将要输出的数据传输到指定位置,stderr将程序运行的错误信息传输到指定位置。在下方会配合文件相关函数,理解这三个流和文件函数。

7.2、文件光标移动函数 fseek(),文件字节数统计函数 ftell()

1、fseek(FILE* fp,int count,SEEK_SET):此时count需要 >=0,因为当count为正时,代表将光标从指定的位置向后移动count位;当count为负时,代表将文件光标从指定位置向前移动count位;count为0时,代表就让鼠标待在指定的三个位置之一。

//指定文件光标,//待在从文件开头向后移一位的位置fseek(fp, 1, SEEK_SET);//待在当前位置fseek(fp, 0, SEEK_SCUR);//待在从文件尾部向前移一位的位置fseek(fp, -1, SEEK_END);

此时,还暂时没有体现出文件光标移动的意义,fseek()配合着统计光标之前的字节数函数ftell(),就体现出其一部分的作用了。

2、ftell(FILE* fp):统计该文件文件光标之前的数据字节数。如果我们想要通过代码知道一个文件的大小,就可以通过将文件光标移动到文件结尾,再统计光标之前的字节数,就可以知道文件的字节大小了。

将之前写入的内容清除,此时文件中只有12个字符,所以大小为12字节。

7.3、getc(),putc()

1、getc(FILE* fp)函数:从指定文件的文件光标处获取一个数据当作返回值返回。当文件刚被打开时,默认文件光标在文件开头。当getc() 获取到一个数据时,光标自动向后移动一位。

●使用方式:

FILE* fp = fopen("C:\\Users\\86187\\Documents\\hello.txt","a+");assert(fp != NULL);char a = getc(fp);printf("%c", a);//等价于printf("%c", getc(fp));fclose(fp);

连续使用,就可以按顺序获取到文件的数据。

●注意:对于二进制文件,其以二进制方式保存数据,如果该文件中刚好有 -1,其值与文件结束标记EOF的值相同,所以用getc()函数获取二进制文件的数据时可能会被误导。

char a = 0;while ((a = getc(fp)) != EOF) {printf("%c", a);}

扩充:

若我们将getc获取数据的来源从文件改为输入流stdin,我们就实现的getchar()的功能:getc(stdin); <=> getchar(); //所以getchar()是getc()的特殊实现。//这也是一个专业术语--重定向,的实现。

2、putc(int a,FILE* fp)函数:将数据a输入到fp指向的文件中。如果文件是以写的w+或r+方式打开,a会从文件头开始保存,覆盖原数据;如果文件以a+方式打开,数据就从文件结尾开始保存。当a值的大小在ASCII码范围内,a被保存后,可以被识别为我们常见的字符;如果超出范围,我们打开文件就可能会显示乱码。

扩充:

若我们将putc输出数据的终端从文件改为输出流stdout,我们就实现的putchar()的功能:putc('a',stdout); <=> putchar(); //所以putchar()是putc()的特殊实现。

7.3、fgets(),fputs()

1、fgets(char* buff,int count,FILE* fp):将fp指向文件中的count个数据获取到字符串buff中。

当我们将其数据来源重定向为stdin时,我们就实现了gets()函数。读者可自行验证。

2、fputs(const char* buff,FILE* fp):将字符串buff中的数据输出到fp指向文件中。

当我们将其数据输出终端重定向为stdout时,我们就实现了puts()函数。读者可自行验证。

7.4、 fscanf()、fprintf()

1、fscanf(FILE*fp,Format 数据格式,数据去向):从文件中获取数据,以指定格式输入到指定去向。如:

//将fp指向的文件中光标位置的后两个数据//以字符形式分别保存到a、b中char a = 0, b = 0;fscanf(fp, "%c%c", &a,&b);printf("%c,%c",a,b);

将数据来源从文件修改为输入流stdin时,就可以实现scanf()函数:

2、fprintf(FILE* fp,Format 数据格式, 数据来源):将数据来源的数据以指定数据格式,写入文件fp。如:

将数据去向从文件修改为输出流stdout,就实现了printf()函数。读者可自行验证。

8、总结

1、在输入文件路径时,要注意斜杠问题,要使用双反斜杠"\\"或正斜杠'/'代替。

2、文件类型分为文本文件和二进制文件两种,但最根本的数据形式还是二进制机器码。我们在文本文件中编辑的数据都是各类字符,是我们认识的,所以文本文件以文本解析工具打开后我们还能认识其中内容。但二进制文件中全是机器码,其排列组合就不一定是我们能认识的字符或ASCII码表中的字符了,所以二进制文件以文本解析工具打开的话,其中有些字符我们能认识,但大部分都是乱码形式。

3、文本文件与二进制文件的打开模式相同,只不过多加了个字符b。

4、如果以一个字节一个字节的形式从二进制文件中读取数据,有可能读取到 -1的二进制(与文件结束标志相同)。让程序误以为读取到文件末尾了,导致出错。

5、文件数据读取与写入有缓冲区帮助,目的是为了减少I/O调用,避免浪费资源与时间。

6、各类从键盘输入和屏幕输出的函数,其实都是各类文件数据读取和写入函数的特殊实现。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。