从零开始的C语言:文件操作与数据存储(上)(文件的分类,文件的打开和关闭)

文件操作与数据存储

  1. 为什么使⽤⽂件?

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

  2. 什么是⽂件?

    磁盘(硬盘)上的⽂件是⽂件。

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

程序文件

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

数据文件

⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件。

流和标准流

我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进⾏⽅便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河。

C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。

⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。

标准流

那为什么我们从键盘输⼊数据,向屏幕上输出数据,并没有打开流呢?

那是因为C语⾔程序在启动的时候,默认打开了3个流:

• stdin -

标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。

stdout

标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出

流中。

• stderr

标准错误流,⼤多数环境中输出到显⽰器界⾯。

这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。

stdin、stdout、stderr 三个流的类型是: FILE *

通常称为⽂件指针。

C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作。

⽂件指针

缓冲⽂件系统中,关键的概念是"⽂件类型指针",简称"⽂件指针"。

每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系

统声明的,取名 FILE.

例如,VS2013 编译环境提供的 stdio.h 头⽂件中有以下的⽂件类型申明:

c 复制代码
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;

文件的打开和关闭

fopen

FILE * fopen ( const char * filename, const char * mode )

⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件。

在编写程序的时候,在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了指针和⽂件的关系。

ASIIC 规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件。

mode表⽰⽂件的打开模式,下⾯都是⽂件的打开模式:

"r"

只读打开文件 文件必须存在,否则fopen返回NULL 只能读取文件内容,不能写入 / 修改

"w"

只写创建 / 截断文件 文件不存在则创建;存在则清空(截断)内容 打开后文件指针指向开头,写入会覆盖原有内容

"a"

追加写打开 / 创建文件 文件不存在则创建;存在则保留原有内容 写入内容始终追加到文件末尾,文件指针指向末尾

"r+"

读写打开文件 文件必须存在,否则fopen返回NULL 可同时读写,文件指针初始指向开头

"w+"

读写创建 / 截断文件 文件不存在则创建;存在则清空内容 可同时读写,初始指针指向开头

"a+"

读写打开 / 创建文件(追加读 + 写) 文件不存在则创建;存在则保留原有内容 写入始终追加到末尾;读取可从开头开始

fclose

fclose为关闭文件参数为流的指向的空间

c 复制代码
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
	}
	int fclose(pf);
	pf = NULL;
	return 0;
}

在这个代码中text.txt 文件不存在。所以只能返回空指针,用perror标记错误

文件的读写


函数的原型如上;

读写的函数有很多,我们选几个来讲一下他们的基础用法

fgetc

fgetc int fgetc(FILE *stream)

参数为流指向的文件

首先建立一个文本文件

text.txt

用vs打开

代码如下

c 复制代码
int main()
{
	FILE* pf = fopen("test.txt","r");
	if (pf==NULL)//防止为空指针,提前结束
	{
		perror("fopen");
		return 1;//终止
	}
	int c = 0;
	while ((c=fgetc(pf))!=EOF)//语法格式
	{
		printf("%c", c);
	}

	fclose(pf);//关闭文件
	pf = NULL;//置为空指针
	return 0;
}

fputc和fputs

fputs输出字符串

fputc输出单个字符

fputs读取字符串

c 复制代码
int main()
{
	FILE* pr = fopen("test.txt","w");
	if (pr==NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("hello world",pr);
	fclose(pr);
	pr = NULL;
	return 0;
}

scanf fscanf scanf

printf fprintf sprintf辨析

scanf/printf:面向标准输入 / 输出流(键盘 / 屏幕);

fscanf/fprintf:面向文件流;

sscanf/sprintf:面向内存字符串。

c 复制代码
scanf	int scanf(const char *format, ...);	标准输入(键盘)	从键盘按格式读取数据到变量	直接读取用户输入
fscanf	int fscanf(FILE *stream, const char *format, ...);	文件流	从指定文件按格式读取数据到变量	读取文件中的格式化数据
sscanf	int sscanf(const char *str, const char *format, ...);	内存字符串	从指定字符串按格式解析数据到变量	解析字符串中的结构化数据
c 复制代码
int main()
{
	int a = 0;
	/*printf("%s","hello world\n");
	fprintf(stdout, "%s", "hello world\n");*/
	/*scanf("%d",&a);*/
	fscanf(stdin,"%d",&a);
	printf("%d",a);
	system("pause");)
	return 0;
}

文件的随机读写

fseek

根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)。

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

相关推荐
SELSL3 小时前
标准IO总结
linux·c语言·标准io·stdio·标准io与文件io的区别
小柯博客3 小时前
从零开始打造 OpenSTLinux 6.6 Yocto 系统 - STM32MP2(基于STM32CubeMX)(九)
c语言·stm32·单片机·嵌入式硬件·物联网·嵌入式·yocto
我是哈哈hh3 小时前
【Python数据分析】数据可视化(全)
开发语言·python·信息可视化·数据挖掘·数据分析
良木生香3 小时前
【诗句结构-初阶】详解栈和队列(2)---队列
c语言·数据结构·算法·蓝桥杯
拾贰_C3 小时前
【python| pytorch】卸载py库,手动法
开发语言·pytorch·python
!停3 小时前
数据在内存中的存储(2)
开发语言·c++·算法
龙山云仓3 小时前
No098:黄道婆&AI:智能的工艺革新与技术传承
大数据·开发语言·人工智能·python·机器学习
是喵斯特ya3 小时前
python开发web暴力破解工具(基础篇)
开发语言·python·web安全
量子炒饭大师3 小时前
Cyber骇客的LIFO深渊与FIFO管道 ——【初阶数据结构与算法】栈与队列
c语言·数据结构·c++·链表