百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

C语言这些常见标准文件该如何使用?很基础也很重要

wptr33 2025-02-11 13:47 32 浏览

谈到文件,先了解下什么是文本文件二进制文件的区别吧!

1、文本文件:存储时是将字符的ASCII值存在磁盘中,取的时候将数值(ASCII)翻译成对应的字符;

2、二进制文件:存取的都是二进制;

文件流指针:

当打开一个文件时,系统会返回一个结构体,这个结构体有对此文件操作的所有信息

调用fopen时(fopen的返回值: 如果成功返回FILE结构体地址,失败返回NULL;

返回的文件流指针标识了打开的那个文件),系统返回这个结构体地址,比如如下所示:

FILE*P = fopen("test.txt");

说太多的东西不如代码演示一遍,代码如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 


int main(){
	// 打开一个文件,成功则返回这个FLIE结构体地址,失败则返回NULL;
	FILE *fp = fopen("./test.txt", "w");
	if (NULL == fp) {
		perror(""); // 打印输错的信息
		return;
	}
	fclose(fp); // 关闭文件
	return 0;
}

以上代码是在相对路径下执行的,为了直接在vs中调试运行。注意:对于相对路径相对的是工程文件。

设备文件:

但启动一个程序时,系统会打开三个设备文件,分别是:

1、stdin 标准输入文件:

FILE *stdin = fopen(stdin,"r")

2、stdout 标准输出文件:

FILE *stdout = fopen(stdout,"w")

3、stderr 标准错误文件:

FILE *stderr = fopen(stderr,"w")

利用fputc() 和 fgetc()读写文件:

1、fputc():

格式:

int fputc(int ch, FILE * stream);
/*
功能:将ch转换为unsigned char后写入stream指定的文件中
参数:
       ch:需要写入文件的字符
       stream:文件指针
返回值:
       成功:成功写入文件的字符
       失败:返回-1
*/

作用:写入一个字符到文件当中。

代码演示如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 


int main(){
	// 打开一个文件,成功则返回这个FLIE结构体地址,失败则返回NULL;
	FILE *fp = fopen("./test.txt", "w");
	if (NULL == fp) {
		perror(""); // 打印输错的信息
		return;
	}
	char strBuf[] = "abcde";
	int n = 0;
	while (strBuf[n] != 0) {
		fputc(strBuf[n], fp);
		n++;
	}
	fclose(fp); // 关闭文件
	return 0;
}

2、fgetc():

格式

int fgetc(FILE * stream);
/*
功能:从stream指定的文件中读取一个字符
参数:
       stream:文件指针
返回值:
       成功:返回读取到的字符
       失败:-1
*/

代码演示如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 


int main(){
	// 打开一个文件,成功则返回这个FLIE结构体地址,失败则返回NULL;
	FILE *fp = fopen("./test.txt", "r");
	if (NULL == fp) {
		perror(""); // 打印输错的信息
		return;
	}
	char strBuf[128] = "";
	int n = 0;
	while ((strBuf[n++] = fgetc(fp)) != EOF);
	printf("%s\n", strBuf);
	fclose(fp); // 关闭文件
	return 0;
}

在上面代码提到了用“EOF”作为文件的结尾,也要提下 feof() 这个函数的使用方法。

为什么要提到这个函数,主要是如果读取文件不是纯文本的时候,有像-1这种数字,那么就不可以使用EOF(-1)作为文件的结尾,就需要用到foef()函数。

格式:

int feof(FILE * stream);
/*
功能:检测是否读取到了文件结尾。判断的是最后一次“读操作的内容”,不是当前位置内容(上一个内容)。
参数:
       stream:文件指针
返回值:
       非0值:已经到文件结尾
       0:没有到文件结尾
*/

用代码形式演示如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 


int main(){
	// 打开一个文件,成功则返回这个FLIE结构体地址,失败则返回NULL;
	FILE *fp = fopen("./test.txt", "r");
	if (NULL == fp) {
		perror(""); // 打印输错的信息
		return;
	}
	char strBuf[128] = "";
	int n = 0;
	do {
		strBuf[n++] = fgetc(fp);
	} while (!feof(fp)); // 非0值读到文件末尾,取反则为未读到文件末尾
	printf("%s\n", strBuf);
	fclose(fp); // 关闭文件
	return 0;
}

fgets()与fputs():

1、fgets(读取字符串):

作用:从文件读取字符串,fgets读取中遇到\n结束;

格式:

char * fgets(char * str, int size, FILE * stream);
/*
功能:从stream指定的文件内读入字符,保存到str所指定的内存空间,直到出现换行字符、读到文件结尾或是已读了size - 1个字符为止,最后会自动加上字符 '\0' 作为字符串结束。
参数:
       str:字符串
       size:指定最大读取字符串的长度(size - 1)
       stream:文件指针
返回值:
       成功:成功读取的字符串
       读到文件尾或出错: NULL
*/

2、fputs(写入字符串):

作用:向文件写入字符串;

格式:

int fputs(const char * str, FILE * stream);
/*
功能:将str所指定的字符串写入到stream指定的文件中,字符串结束符 '\0'  不写入文件。
参数:
       str:字符串
       stream:文件指针
返回值:
       成功:0
       失败:-1
*/

fprintf()与fscanf():

1、fprintf():

作用:组包函数,写文件;

格式:

int fprintf(FILE * stream, const char * format, ...);
/*
功能:根据参数format字符串来转换并格式化数据,然后将结果输出到stream指定的文件中,指定出现字符串结束符 '\0'  为止。
参数:
       stream:已经打开的文件
       format:字符串格式,用法和printf()一样
返回值:
       成功:实际写入文件的字符个数
       失败:-1
*/

2、fscanf():

作用:拆包函数(读文件):

格式:

int fscanf(FILE * stream, const char * format, ...);
/*
功能:从stream指定的文件读取字符串,并根据参数format字符串来转换并格式化数据。
参数:
       stream:已经打开的文件
       format:字符串格式,用法和scanf()一样
返回值:
       成功:参数数目,成功转换的值的个数
       失败: - 1
*/

fwrite()写入函数与fread()读取函数:

1、fwrite()写入函数:

格式:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
/*
功能:以数据块的方式给文件写入内容
参数:
       ptr:准备写入文件数据的地址
       size: size_t 为 unsigned int类型,此参数指定写入文件内容的块数据大小
       nmemb:写入文件的块数,写入文件数据总大小为:size * nmemb
       stream:已经打开的文件指针
返回值:
       成功:实际成功写入文件数据的块数目,此值和 nmemb 相等
       失败:0
*/

需要注意的是:在第二个参数写1,,返回值即是写入的块数也是写入的字节数。

2、fread()读取函数:

格式:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
/*
功能:以数据块的方式从文件中读取内容
参数:
       ptr:存放读取出来数据的内存空间
       size: size_t 为 unsigned int类型,此参数指定读取文件内容的块数据大小
       nmemb:读取文件的块数,读取文件数据总大小为:size * nmemb
       stream:已经打开的文件指针
返回值:
成功:实际成功读取到内容的块数,如果此值比nmemb小,但大于0,说明读到文件的结尾。
       失败:0
*/

文件的随机读写:

分别为三个函数:如下所示:

1、fseek():

作用:可以移动光标。

格式:

int fseek(FILE *stream, long offset, int whence);
/*
功能:移动文件流(文件光标)的读写位置。
参数:
       stream:已经打开的文件指针
offset:根据whence来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence往右移动,如果是负数,则相对于whence往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再次写入时将增大文件尺寸。
       whence:其取值如下:
              SEEK_SET:从文件开头移动offset个字节
              SEEK_CUR:从当前位置移动offset个字节
              SEEK_END:从文件末尾移动offset个字节
返回值:
       成功:0
       失败:-1
*/

2、rewind():

作用:将光标移动到开头,和fseek(fp,0,SEEK_SET)一样。

格式:

void rewind(FILE *stream);
/*
功能:把文件流(文件光标)的读写位置移动到文件开头。
参数:
       stream:已经打开的文件指针
返回值:
       无返回值
*/

3、 ftell():

格式:

long ftell(FILE *stream);
/*
功能:获取文件流(文件光标)的读写位置。
参数:
       stream:已经打开的文件指针
返回值:
       成功:当前文件流(文件光标)的读写位置
       失败:-1
*/

获取文件状态信息stat:

格式:

int stat(const char *path, struct stat *buf);
/*
功能:获取文件状态信息
参数:
path:文件名
buf:保存文件信息的结构体
返回值:
成功:0
失败:-1
*/

struct stat {
       dev_t         st_dev;         //文件的设备编号
       ino_t         st_ino;          //节点
       mode_t        st_mode;   //文件的类型和存取的权限
       nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
       uid_t         st_uid;         //用户ID
       gid_t         st_gid;         //组ID
       dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
       off_t         st_size;        //文件字节数(文件大小)
       unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
       unsigned long st_blocks;    //块数
       time_t        st_atime;     //最后一次访问时间
       time_t        st_mtime;    //最后一次修改时间
       time_t        st_ctime;     //最后一次改变时间(指属性)
};

代码演示一下,如下所示:

#define __CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include 
#include 

int main(){
	struct stat stu;
	int res = 0;
	res = stat("./test.txt", &stu);
	if (res < 0) {
		printf("没找到文件!\n");
	}
	printf("文件大小为:%d\n", stu.st_size);
	system("pause");
	return 0;
}

我这个文件因为是存在,而且文件有内容,所以会打印出文件大小,如下图所示:

remove()与rename():

1、remove():

格式:

int remove(const char *pathname);
/*
功能:删除文件
参数:
       pathname:文件名
返回值:
       成功:0
       失败:-1
*/

2、rename():

格式:

int rename(const char *oldpath, const char *newpath);
/*
功能:把oldpath的文件名改为newpath
参数:
oldpath:旧文件名
newpath:新文件名
返回值:
成功:0
失败: - 1
*/

文件缓冲区:

注意问题:

缓冲区:就是内存中的一块临时的空间,同时普通文件刷新缓冲区的方法,有以下3种:

1、缓冲区满了;2、程序正常退出时;3、利用fflush函数强制刷新。

windows与Linux的区别:

1、Windows下标准输出stdout文件没有缓冲区;

2、Linux有缓冲区;

标准输入不能调用fflush强制刷新;

3、\n换行的问题。

在windows,输入nihao\n时,存储的是nihao\r\n,取出时是nihao\n,当在Linux系统下打开windows存储的文件时,就会多了一个\r。

在Linux,输入nihao\n时,存储和取出都是nihao\n,而在windows下打开Linux存储的文件时,发现没有换行。

相关推荐

oracle数据导入导出_oracle数据导入导出工具

关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...

继续学习Python中的while true/break语句

上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个else解...

python continue和break的区别_python中break语句和continue语句的区别

python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...

简单学Python——关键字6——break和continue

Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...

2-1,0基础学Python之 break退出循环、 continue继续循环 多重循

用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...

Python 中 break 和 continue 傻傻分不清

大家好啊,我是大田。今天分享一下break和continue在代码中的执行效果是什么,进一步区分出二者的区别。一、continue例1:当小明3岁时不打印年龄,其余年龄正常循环打印。可以看...

python中的流程控制语句:continue、break 和 return使用方法

Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...

L017:continue和break - 教程文案

continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...

作为前端开发者,你都经历过怎样的面试?

已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...

面试被问 const 是否不可变?这样回答才显功底

作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...

2023金九银十必看前端面试题!2w字精品!

导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。答案:CSS的盒模型是用于布局和定位元素的概念。它由内容区域...

前端面试总结_前端面试题整理

记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...

由浅入深,66条JavaScript面试知识点(七)

作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录由浅入深,66条JavaScript面试知识点(一)由浅入深,66...

2024前端面试真题之—VUE篇_前端面试题vue2020及答案

添加图片注释,不超过140字(可选)1.vue的生命周期有哪些及每个生命周期做了什么?beforeCreate是newVue()之后触发的第一个钩子,在当前阶段data、methods、com...

今年最常见的前端面试题,你会做几道?

在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...