c语言-文件操作

这篇具有很好参考价值的文章主要介绍了c语言-文件操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1.为什么使用件?

如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。

2. 什么是文件?

磁盘上的文件是文件。
但是在程序设计中,我们⼀般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。
(1)程序文件

程序文件包括源程序文件(后缀为.c),目标⽂件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。

(2)数据文件

文件的内容不⼀定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

我们接下来要讨论的就是数据文件

在以前我们所处理数据的输入输出都是以终端为对象的,即从终端的键盘输⼊数据,运行结果显示到显示器上。
其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上文件。

(3)文件名

⼀个文件要有⼀个唯⼀的文件标识,以便用户识别和引用。 文件名包含3部分:文件路径+文件名主干+文件后缀 例如:
c:\code\test.txt

3. 二进制文件和文本文件?

根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。
如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
⼀个数据在内存中是怎么存储的呢?
字符⼀律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。

4. 文件的打开和关闭

(1)关于流和标准流
流:

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输入输出操作各不相同,为了方便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。
C程序针对文件、画面、键盘等的数据输入输出操作都是通过流操作的。
⼀般情况下,我们要想向流里写数据,或者从流中读取数据,都是要打开流,然后操作。

标准流:

那为什么我们从键盘输入数据,向屏幕上输出数据,并没有打开流呢? 那是因为C语言程序在启动的时候,默认打开了3个流:
• stdin -
标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。
• stdout -
标准输出流,大多数的环境中输出至显示器界面,printf函数就是将信息输出到标准输出流中。
• stderr -
标准错误流,⼤多数环境中输出到显示器界面。 这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进行输入输出操作的。
stdin、stdout、stderr 三个流的类型是: FILE* ,通常称为文件指针。 C语言中,就是通过 FILE*
的文件指针来维护流的各种操作的。

(2)文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了⼀个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名FILE
我们可以通过文件指针来使用它们

文件指针的创建

FILE * pf

定义pf是⼀个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是⼀个结构体变量)。通过该⽂件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够间接找到与它关联的文件

如:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(3)文件的打开和关闭
我们使用文件时应该要先打开文件,当然在程序结束时也要关闭文件
我们分别通过两个函数来打开和关闭文件
打开:使用fopen函数

//打开文件
FIL* E pf=fopen ( const char * filename, const char * mode );

filename指的是文件名
mode指的是打开的方式
打开失败返回NULL
关闭:使用fclose函数

//关闭文件
int fclose ( FILE * stream );

stream指的是文件指针pf

打开模式
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
注意:使用写的时候文件的内容会先被清空哦
使用:

#include<stdio.h>
int main() {
	
	  //打开
		FILE* pf = fopen("data.txt", "w");
		//判断是否成功打开
		if (pf == NULL) {
			perror("fopen");
			return 1;
		}
		//使用文件
		for(int i=0;i<26;i++)
		fputc('a'+i, pf);
		//关闭
		fclose(pf);
		pf = NULL;
		return 0;
	}

5. 文件的顺序读写

顺序函数介绍:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(1)fputc函数
格式:

int fputc ( int character, FILE * stream );

参数:character:要写入的字符的 int 提升。写入时,该值在内部转换为无符号字符
stream:文件指针
返回值:成功后,将返回写入的字符。
如果发生写入错误,则返回 EOF 并设置错误指示符 (ferror)。
作用:
将字符输出到文件里
使用

//fputc
int main() {
	//打开一个文件
	FILE* pf = fopen("data.txt", "w");//data.txt--文件名  w-写(写到文件中)
	//判断是否为空
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	//使用
	for(int i=0;i<26;i++)
		//
	fputc('a'+i, pf);//将数据输出到文件里
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
打开文件就可以看到成功输出到文件中了
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(2)fgetc函数
格式:

int fgetc ( FILE * stream );

参数:
指向标识输入流的 FILE 对象的指针。
返回值:
成功后,将返回字符读取(提升为 int 值)。
返回类型为 int 以适应特殊值 EOF,该值表示失败:
如果位置指示器位于文件末尾,则该函数返回 EOF 并设置流的 eof 指示(feof)。
如果发生其他读取错误,该函数也会返回 EOF,但会设置其错误指示器 (ferror
作用:
将文件字符输入
使用:

int main() {
	char arr[27];//存储字符
	FILE* pf = fopen("data.txt", "r");//打开文件,r-读(从文件中读取)
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	//将字符输入到字符数组中
	for (int i = 0; i < 26; i++)
		arr[i]=fgetc(pf);
	arr[26] = '\0';
	printf("%s\n", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(3)fputs函数
格式:

int fputs ( const char * str, FILE * stream );

参数:
str :包含要写入流的内容的 C 字符串
stream :指向标识输出流的 FILE 对象的指针。
返回值:
成功后,将返回一个非负值。
出错时,该函数返回 EOF 并设置错误指示器 (ferror)。
作用:
将一个字符串输出到文件中
使用:

int main() {

	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	//使用
	fputs("abcder", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
打开文件观察
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(4)fgets函数
格式:

char * fgets ( char * str, int num, FILE * stream );

参数:
str:指向复制字符串读取的 char数组的指针
num:要复制到 str 中的最大字符数(包括终止 null 字符),真实输入的是num-1个字符
stream:文件指针
返回值:成功后,该函数返回 str。
如果在尝试读取字符时遇到文件末尾,则设置 eof 指示符 (feof)。如果在读取任何字符之前发生这种情况,则返回的指针为 null 指针(并且 str 的内容保持不变)。
如果发生读取错误,则设置错误指示符 (ferror) 并返回 null 指针(但 str 指向的内容可能已更改)。

作用:
将文件中的字符串输入
使用:

 //fgets
int main() {
	int arr[26];
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	//使用
		 fgets(arr,5,pf);
		 printf("%s", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(5)fprintf函数
格式:

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

参数:
stream:指向标识输出流的 FILE 对象的指针。
format:这是一个可变参数,和pringf类似
返回值:功后,将返回写入的字符总数。
如果发生写入错误,则设置错误指示符(ferror)并返回负数。
如果在写入宽字符时发生多字节字符编码错误,则将 errno 设置为 EILSEQ 并返回负数。
作用:将按格式指向的 C 字符串写入流。如果 format 包含格式说明符(以 % 开头的子序列),则格式化 format 后面的其他参数并将其插入到生成的字符串中,以替换其各自的说明符。
使用:

int main() {

	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	//使用
	fprintf(pf, "%d %d %c", 21,55, 'c');
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(6)fscanf函数
格式:

int fscanf ( FILE * stream, const char * format, ... );

参数:与fprintf一样
返回值:
成功后,该函数返回已成功填充的参数列表的项数。此计数可以与预期的项目数匹配。
如果在读取时发生读取错误或达到文件末尾,则设置正确的指示器(feof 或 ferror)。而且,如果在成功读取任何数据之前发生任何一种情况,则返回 EOF。
作用:
从流中读取数据,并根据参数格式将其存储到其他参数所指向的位置。
其他参数应指向已分配的对象,该对象由格式字符串中的相应格式说明符指定。
使用:

int main() {
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	int a, b;
	char  c;
	//使用
	fscanf(pf, "%d %d %c",&a,&b,&c);
	printf("%d %d %c", a, b, c);
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
(7)fwrite函数
格式:

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

参数:
prt:指向要写入的元素数组的指针,转换为 const void*
size:要读取的每个元素的大小(以字节为单位)。size_t 是无符号整型。
count:元素的数量,每个元素的大小为 bytes。size_t 是无符号整数类型。
stream:文件指针
返回值:返回成功写入的元素总数。
如果此数字与 count 参数不同,则写入错误会阻止函数完成。在这种情况下,将为流设置错误指示器 (ferror)。
如果 size 或 count 为零,则函数返回零,错误指示器保持不变。
作用:
进行二进制文件的输出
使用:

//fwrite
int main() {
	int  p[3] = {1,4,5};
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	fwrite(p, 4, 3, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
由于我们这个是文本文件所以无法看到内容

(8)fread函数
格式:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

参数:
ptr:指向大小至少为 (sizecount) 字节的内存块的指针,该块转换为 void
size:要读取的每个元素的大小(以字节为单位)。size_t 是无符号整型。
count:元素的数量,每个元素的大小为 bytes。size_t 是无符号整数类型。
stream:文件指针
返回值:
返回成功读取的元素总数。
如果此数字与 count 参数不同,则表示读取时发生读取错误或已达到文件末尾。在这两种情况下,都设置了正确的指示器,可以分别用 ferror 和 feof 进行检查。
如果 size 或 count 为零,则该函数返回零,并且流状态和 ptr 指向的内容保持不变。size_t 是无符号整数类型。
作用:
进行二进制文件的输入
使用:

//fread
int main() {
	int arr[3] = { 0 };
		FILE* pf = fopen("data.txt", "r");
		if (pf == NULL) {
			perror("fopen");
			return 1;
		}
	//使用
		fread(arr, 3, 4, pf);
		printf("%d ", arr[0]);
		printf("%d ", arr[1]);
		printf("%d ", arr[2]);
		fclose(pf);
		pf = NULL;
		return 0;
	}

运行结果:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享

6. 文件的随机读写

(1)fseek函数
格式:

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

参数:
stream:文件指针
offset:偏移多少
origin:从哪里开始偏移c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享
返回值:
如果成功,该函数将返回零。
否则,它将返回非零值。
如果发生读写错误,则设置错误指示器 (ferror)。

作用:
对光标位置进行偏移
使用:

int main() {
	char arr[27];//存储字符
	FILE* pf = fopen("data.txt", "r");//打开文件,r-读(从文件中读取)
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	int i;
	//将字符输入到字符数组中
	//使用,偏移到第二个位置
	fseek(pf, 2, SEEK_SET);
	for ( i = 0; i < 25; i++)
		arr[i]=fgetc(pf);
	arr[24] = '\0';
	printf("%s\n", arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
文件内容是abcdefghijklmnopqrstuvwxyz
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享

(2)ftell函数
格式:

long int ftell ( FILE * stream );

参数:
一个文件指针
返回值:
返回偏移的位置(以文件开头为标准)
作用:
记录光标位置
使用:

int main() {
	char arr[27];//存储字符
	FILE* pf = fopen("data.txt", "r");//打开文件,r-读(从文件中读取)
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	int i;
	fseek(pf, 2, SEEK_SET);
	for ( i = 0; i < 25; i++)
		arr[i]=fgetc(pf);
	arr[24] = '\0';
	//使用:
	int t=ftell(pf);
	printf("%d\n",t);
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享

(3)rewind
格式:

void rewind ( FILE * stream );

参数:文件指针
返回值为空
作用:
让文件指针的位置回到文件的起始位置

7. 文件读取结束的判定

(1)feof函数
格式:

int feof ( FILE * stream );

参数:文件指针
返回值:
如果设置了与流关联的文件结束指示符,则返回非零值。
否则,返回零。
作用:当文件读取结束的时候,判断是读取结束的原因是否是:遇到文件尾结束。
注意:在文件读取过程中,不能⽤feof函数的返回值直接来判断文件的是否结束
文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets)
例如:
• fgetc 判断是否为 EOF .
• fgets 判断返回值是否为 NULL .
(2)ferror函数
格式:

int ferror ( FILE * stream );

参数:文件指针
返回值:
如果设置了与流关联的错误指示器,则返回非零值。
否则,返回零。
作用:检查是否出现错误

(3)关于上述函数的使用

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
 int c; // 注意:int,⾮char,要求处理EOF
 FILE* fp = fopen("test.txt", "r");
 if(!fp) {
 perror("File opening failed");
 return EXIT_FAILURE;
 }
 //fgetc 当读取失败的时候或者遇到⽂件结束的时候,都会返回EOF
 while ((c = fgetc(fp)) != EOF) // 标准C I/O读取⽂件循环
 { 
 putchar(c);
 }
 //判断是什么原因结束的
 if (ferror(fp))
 puts("I/O error when reading");
 else if (feof(fp))
 puts("End of file reached successfully");
 fclose(fp);
 return 0;

8. 文件缓冲区

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

为什么会有缓冲区:

a.提高效率
b.因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。
如果不做,可能导致读写文件的问题

过程图:
c语言-文件操作,c语言主要知识点,c语言,开发语言,经验分享

以上就是我的分享了,如果有什么错误,欢迎在评论区留言。
最后,谢谢大家的观看!文章来源地址https://www.toymoban.com/news/detail-771981.html

到了这里,关于c语言-文件操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机语言知识点梳理

    python是一门强类型、动态型、解释型语言语言 JavaScript是一门弱类型、动态性、解释型语言 typescript是一门强类型、静态型、编译型语言 Java是一门强类型、静态型、编译型语言 变量大小写区分 html css sql java javascript python typescript c 弱类型语言和强类型语言 强类型语言也称为强

    2024年02月09日
    浏览(45)
  • 8086 汇编语言知识点梳理

    机器语言是机器指令的集合 机器指令是一台机器可以正确执行的命令 机器指令由一串二进制数表示 汇编语言的主体是汇编指令 汇编指令是机器指令便于记忆的书写格式 汇编指令是机器指令的 助记符 汇编指令:机器码的助记符,有对应的机器码 伪指令::没有对应的机器

    2024年02月08日
    浏览(50)
  • 【C语言】指针知识点笔记(2)

    目录 一、野指针 二、assert断言 三、指针的使用和传址调用 四、数组名的理解 五、使用指针访问数组

    2024年01月18日
    浏览(42)
  • 【详解】C语言冷门知识点之--位段

    下面是维基百科对位段的解释:   位段(或称“位域”,Bit field)为一种数据结构,可以把数据以位的形式紧凑的储存,并允许程序员对此结构的位进行操作。这种数据结构的好处: 可以使数据单元节省储存空间,当程序需要成千上万个数据单元时,这种方法就显得尤为重

    2024年02月16日
    浏览(40)
  • 单片机----汇编语言入门知识点

    目录 汇编语句的格式 汇编语句的两个基本语句 子程序的调用 查表程序设计 1.x和y均为单字节数的查表程序设计 2.x为单字节数y为双字节数的查表程序设计 3.x和y均为双字节数的查表程序设计 分支转移程序设计 1.单分支选择结构 2.多分支选择结构 循环程序设计 (1) 计数循环控

    2024年04月28日
    浏览(46)
  • 开发知识点-RabbitMQ

    RabbitMQ是一个使用Erlang语言开发 开源的消息中间件项目(Message Broker), 采用Mozilla Public License(MPL)开源许可证。这意味着任何人都可以自由获取、使用、修改和分发RabbitMQ的源代码。 实现了高级消息队列协议(AMQP)并提供可靠的、异步的消息传递机制。 可以让你在不同的

    2024年02月02日
    浏览(39)
  • 网络开发过程详细知识点

     网络生命周期 至少包括系统构思与计划、分析和设计、运行和维护的过程。  常见的迭代周期分为四阶段周期、五阶段周期、六阶段周期。   网络开发过程根据五阶段迭代周期模型可被分为 五个阶段:    需求分析、现有网络分析、确定网络逻辑结构、确定网络物理结构

    2024年02月07日
    浏览(38)
  • C++入门知识点——解决C语言不足

    😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️Take your time ! 😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️ 💥个人主页:🔥🔥🔥大魔王🔥🔥🔥 💥所属专栏:🔥魔王的修炼之路–C++🔥 如果你觉得这篇文章对你有帮助,请在文章结尾处留下你的 点赞 👍和 关注 💖,支持一下博主

    2024年02月12日
    浏览(43)
  • C语言:数组、字符串知识点整理:

    补充 :数组长度= sizeof(arr)/sizeof(arr[0]) 注意: !!! 不适用于当arr 充当形参时(函数传参) !!! 因为函数 传递 的是 int arr[0] 的 地址(指针) ,而 不是数组内容 , 若在此情况计算整形数组长度         在X86系统下,指针大小为 4 ,所以计算结果为4/4=1;       

    2024年03月10日
    浏览(60)
  • C语言指针入门学习、知识点梳理(四)

    本篇内容:指针星号的三种含义以及指针在函数调用时,与实参、形参的变量传递关系,如何通过被调函数修改主调函数普通变量的值。 传送门: C语言指针入门学习、概念梳理(一) C语言指针入门学习、概念梳理(二) C语言指针入门学习、知识点梳理(三) C语言指针入门

    2024年02月09日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包