Linux文件IO(2):使用标准IO进行文件的打开、关闭、读写、流定位等相关操作

news2024/11/13 8:11:23

目录

前言

文件的打开和关闭的概念

文件的打开

文件的打开函数

文件打开的模式

文件的关闭

文件的关闭函数

注意事项

字符的输入(读单个字符)

字符输入的函数

注意事项

字符的输出(写单个字符)

字符输出的函数

注意事项

行输入(读取整个行)

行输入的函数

注意事项

行输出(写整行)

行输出的函数

二进制读写

文本文件和二进制的区别

二进制读写函数

注意事项

流的刷新

流的刷新函数

流的定位

流的定位函数

注意事项

判断流是否出错和结束

判断流是否出错和结束函数

格式化输出

格式化输出函数

格式化输入

格式化输入函数

代码练习

要求

具体实现代码

测试结果

总结


前言

上文对标准IO、流及缓冲区的概念进行介绍并进行了相关实验,上文链接点这里,本文来介绍使用标准IO进行文件的打开、关闭、读、写等相关操作。

文件的打开和关闭的概念

打开就是占用资源

关闭就是释放资源

文件的打开

文件的打开函数

FILE *fopen (const char *path, const char *mode);

path:普通文件当前路径不需要加目录,其他要使用完成的路径

mode:文件打开的模式

返回值:出错返回NULL,所以使用fopen函数必须判断是否为空

文件打开的模式

"r"或"rb"以只读方式打开文件,文件必须存在。
"r+"或"r+b"以读写方式打开文件,文件必须存在
"w"或"wb"以只写方式打开文件,若文件存在则文件长度清为0。若文件不存在则创建。
"w+"或"w+b"以读写方式打开文件,其他同"w"。
"a"或"ab"以只写方式打开文件,若文件不存在则创建;向文件写入的数据被追加到文件末尾。
"a+"或"a+b"以读写方式打开文件。其他同"a"。

文件的关闭

文件的关闭函数

int fclose(FILE *stream)

fclose()调用成功返回0,失败返回EOF(-1),并设置errno。

流关闭时自动刷新缓冲中的数据并释放缓冲区,比如:常规文件把缓冲区内容写入磁盘。

当一个程序正常终止时,所有打开的流都会被关闭。

注意事项

fclose()函数的入参stream必须保证为非空,否则出现断错误。

字符的输入(读单个字符)

字符输入的函数

int  fgetc(FILE *stream);
int  getc(FILE *stream);   //宏
int  getchar(void);

成功时返回读取的字符,若到文件末尾或出错时返回EOF(-1)。

getchar()等同于fgetc(stdin)

getc和fgetc区别就是一个时宏一个是函数

注意事项

1、函数返回值是int类型不是char类型,主要是为了扩展返回值的范围。

2、stdin也是FILE*的指针,是系统定义好的,指向的是标准输入(键盘输入)。

3、打开文件后读取,是从文件开头开始读,读完一个后读写指针会后移。

4、调用getchar会阻塞,等待你的键盘输入

字符的输出(写单个字符)

字符输出的函数

int  fputc(int c, FILE *stream);
int  putc(int c, FILE *stream);
int  putchar(int c);

成功时返回写入的字符;出错时返回EOF。

putchar(c)等同于fputc(c, stdout)。

注意事项

1、返回和输入参数都是int类型

2、遇到这种错误:Bad file descriptor,  很可能是文件打开的模式错误(只读模式去写,只写模式去读)

行输入(读取整个行)

行输入的函数

char  *gets(char *s);  读取标准输入到缓冲区s
char *fgets(char *s, int size, FILE *stream);

成功时返回s,到文件末尾或出错时返回NULL

遇到’\n’或已输入size-1个字符时返回,总是包含’\0’

注意事项

1、gets函数已经被淘汰,因为会导致缓冲区溢出

2、fgets 函数第二个参数,输入的数据超出size,size-1个字符会保存到缓冲区,最后添加’\0’,如果输入数据少于size-1 后面会添加换行符。

行输出(写整行)

行输出的函数

int  puts(const char *s);
int fputs(const char *s,  FILE *stream);

成功时返回非负整数;出错时返回EOF

puts将缓冲区s中的字符串输出到stdout,并追加’\n’

fputs将缓冲区s中的字符串输出到stream,不追加  ‘\n’

二进制读写

文本文件和二进制的区别

存储的格式不同:文本文件只能存储文本。

计算机内码概念:文本符号在计算机内部的编码(计算机内部只能存储数字0101001....,所以所有符号都要编码)

二进制读写函数

size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
//void *ptr  读取内容放的位置指针
//size_t size 读取的块大小
//size_t n 读取的个数
//FILE *fp  读取的文件指针

size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
//void *ptr  写文件的内容的位置指针
//size_t size 写的块大小
//size_t n 写的个数
//FILE *fp  要写的文件指针

注意事项

文件写完后,文件指针指向文件末尾,如果这时候读,读不出来内容。

解决办法:移动指针(后面讲解)到文件头;关闭文件,重新打开

流的刷新

流的刷新函数

int fflush(FILE *fp);

成功时返回0;出错时返回EOF。

将流缓冲区中的数据写入实际的文件。

Linux下只能刷新输出缓冲区,输入缓冲区丢弃。

如果输出到屏幕使用fflush(stdout)。

流的定位

流的定位函数

long ftell(FILE *stream);
long fseek(FILE *stream, long offset,  int whence);
void rewind(FILE *stream);

ftell()成功时返回当前读写位置,出错时返回EOF。

fseek()定位一个流,成功时返回0,出错时返回EOF。

rewind()将流定位到文件开始位置

whence参数:SEEK_SET/SEEK_CUR/SEEK_END

offset参数:偏移量,可正可负

SEEK_SET从距文件开头 offset 位移量为新的读写位置
SEEK_CUR以目前的读写位置往后增加 offset 个位移量
SEEK_END将读写位置指向文件尾后再增加 offset 个位移量

注意事项

1、打开a模式,fseek无效

2、读写流时,当前读写位置自动后移。

判断流是否出错和结束

判断流是否出错和结束函数

#include  <stdio.h>
int ferror(FILE *stream);
int feof(FILE *stream);

ferror()返回1表示流出错;否则返回

feof()返回1表示文件已到末尾;否则返回0

格式化输出

格式化输出函数

int fprintf(FILE *stream, const char *fmt, …);
int sprintf(char *s, const char *fmt, …);

成功时返回输出的字符个数;出错时返回EOF。

格式化输入

格式化输入函数

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

代码练习

要求

1、每隔1s以指定格式 “年-月-日” 分别写入文件和缓冲区;

2、该程序无限循环,直到Ctrl+C中断程序;

具体实现代码

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
int main(int argc,const char* argv)
{
	FILE *fp;
	time_t ctime;
	struct tm *ctimester;
	int linecount = 0;
	char buf[32];

	fp = fopen("1.txt","a+");
	if(fp == NULL)
	{
		perror("fopen");
		return 0;
	}
	//calculate 1.txt  line
	while(fgets(buf,32,fp)!=NULL)
	{
		if(buf[strlen(buf)-1] == '\n')
		{
			linecount++;
		}
	}

	while(1)
	{
    	ctime = time(NULL);
		ctimester = localtime(&ctime);
		printf("%04d-%02d-%02d %02d:%02d:%02d\n",ctimester->tm_year+1900,
				ctimester->tm_mon+1,
				ctimester->tm_mday,
				ctimester->tm_hour,
				ctimester->tm_min,
				ctimester->tm_sec);
		fprintf(fp,"%d, %04d-%02d-%02d %02d:%02d:%02d\n",linecount++,ctimester->tm_year+1900,
				ctimester->tm_mon+1,
				ctimester->tm_mday,
				ctimester->tm_hour,
				ctimester->tm_min,
				ctimester->tm_sec);
		fflush(fp);

		sleep(1);
	}

	fclose(fp);
	return 0;
}

测试结果

总结

本文总结了C语言标准IO的输入、输出、读写、流的刷新定位等相关概念及函数介绍,并根据这些函数进行了一个包含文件打开关闭、读写、格式化输出等内容的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1544758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实战|使用 Node.js 和 htmx 构建全栈应用程序

在本教程中&#xff0c;我将演示如何使用 Node 作为后端和 htmx 作为前端来构建功能齐全的 CRUD 应用程序。这将演示 htmx 如何集成到全栈应用程序中&#xff0c;使您能够评估其有效性并确定它是否是您未来项目的不错选择。 htmx 是一个现代 JavaScript 库&#xff0c;旨在通过…

微服务day07 -- 搜索引擎 ( 数据聚合 + 自动补全 + 数据同步 + ES集群 )

1.数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f; 这些手机的平均价格、最高价格、最低价格&#xff1f; 这些手机每月的销售情况如何&#xff1f; 实现这些…

ydata_profiling:自动生成数据探索报告的Python库

之前在做数据分析的时候&#xff0c;用过一个自动化生成数据探索报告的Python库&#xff1a;ydata_profiling 一般我们在做数据处理前会进行数据探索&#xff0c;包括看统计分布、可视化图表、数据质量情况等&#xff0c;这个过程会消耗很多时间&#xff0c;可能需要上百行代码…

数据库实验(一)SQL Server触发器

目录 触发器的定义 触发器和存储过程的区别 触发器的优点 触发器的作用 触发器的分类 DML触发器 DDL触发器 登录触发器 触发器的工作原理 inserted表 deleted表 创建触发器 编程要求 测试要求&#xff1a; 实验代码&#xff1a; 触发器的定义 触发器是建立在触…

视频推拉流EasyDSS点播平台云端录像播放异常的问题排查与解决

视频推拉流EasyDSS视频直播点播平台可提供一站式的视频转码、点播、直播、视频推拉流、播放H.265视频等服务&#xff0c;搭配RTMP高清摄像头使用&#xff0c;可将无人机设备的实时流推送到平台上&#xff0c;实现无人机视频推流直播、巡检等应用。 有用户反馈&#xff0c;项目现…

深度学习基础知识

本文内容来自https://zhuanlan.zhihu.com/p/106763782 此文章是用于学习上述链接&#xff0c;方便自己理解的笔记 1.深度学习的网络结构 深度学习是神经网络的一种特殊形式&#xff0c;典型的神经网络如下图所示。 神经元&#xff1a;表示输入、中间数值、输出数值点。例如&…

itextPdf生成pdf简单示例

文章环境 jdk1.8&#xff0c;springboot2.6.13 POM依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency><dependency><groupId>com.ite…

【前端面试3+1】01闭包、跨域

一、对闭包的理解 定义&#xff1a; 闭包是指在一个函数内部定义的函数&#xff0c;并且该内部函数可以访问外部函数的变量。闭包使得函数内部的变量在函数执行完后仍然可以被访问和操作。 特点&#xff1a; 闭包可以访问外部函数的变量&#xff0c;即使外部函数已经执行完毕。…

【编译tingsboard】出现gradle-maven-plugin:1.0.11:invoke (default)

出现的错误&#xff1a; [ERROR] Failed to execute goal org.thingsboard:gradle-maven-plugin:1.0.11:invoke (default) on project http: Execution default of goal org.thingsboard:gradle-maven-plugin:1.0.11:invoke failed: Plugin org.thingsboard:gradle-maven-plugi…

输出当前时间

用途&#xff1a;在项目中一些属性中设置当前时间 实例代码 import java.time.LocalDateTime; import java.time.format.DateTimeFormatter;public class time {public static void main(String[] args){LocalDateTime china LocalDateTime.now(); DateTimeFormatter forma…

SpringBoot学习之ElasticSearch下载安装和启动(Mac版)(三十一)

本篇是接上一篇Windows版本,需要Windows版本的请看上一篇,这里我们继续把Elasticsearch简称为ES,以下都是这样。 一、下载 登录Elasticsearch官网,地址是:Download Elasticsearch | Elastic 进入以后,网页会自动识别系统给你提示Mac版本的下载链接按钮 二、安装 下载…

深度学习 - PyTorch基本流程 (代码)

直接上代码 import torch import matplotlib.pyplot as plt from torch import nn# 创建data print("**** Create Data ****") weight 0.3 bias 0.9 X torch.arange(0,1,0.01).unsqueeze(dim 1) y weight * X bias print(f"Number of X samples: {len(…

huawei 华为 交换机 配置 LACP 模式的链路聚合示例 (交换机之间直连)

组网需求 如 图 3-22 所示&#xff0c; SwitchA 和 SwitchB 通过以太链路分别都连接 VLAN10 和 VLAN20 的网络&#xff0c;且SwitchA 和 SwitchB 之间有较大的数据流量。用户希望 SwitchA 和 SwitchB 之间能够提供较大的链路带宽来使相同VLAN 间互相通信。在两台 Switch 设备上…

flask_restful规范返回值之参数设置

设置重命名属性和默认值 使用 attribute 配置这种映射 , 比如&#xff1a; fields.String(attributeusername) 使用 default 指定默认值&#xff0c;比如&#xff1a; fields.String(defaultsxt) from flask import Flask,render_template from flask_restful import A…

C++ 输入与输出

数据输入输出 数据是程序处理的对象&#xff0c;输入输出操作是程序中不可或缺少的部分&#xff0c;C中输入输出操作都是通过函数调用实现的&#xff1b;C提供了一个“标准I/O库”。 格式输出函数-----printf 基本形式是&#xff1a; printf(“控制字符串”,输出项列表); 功能…

openwrt在校园网环境下开启nat6 (ipv6 nat)

如果将路由器接入校园网&#xff0c;我们只能获得一个128位掩码的ipv6地址。这个地址仅供路由器本身使用&#xff0c;而路由器后的设备无法获取到ipv6地址&#xff0c;因此我们可以利用网络地址转换&#xff08;NAT&#xff09;为这些设备分配本地ipv6地址。 下面是openwrt开启…

【C++练级之路】【Lv.16】红黑树(冰与火的碰撞,红与黑的史诗)

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C语言》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、红黑树的概念二、红黑树的模拟实现2.1 结点2.2 成员变量2.3 插入情况一&#xff1a;uncle在左&#xff…

Linux-进程控制(进程创建、进程终止、进程等待)

一、进程创建 1.1 fork函数介绍 在命令行下我们可以通过 ./ exe文件 来创建一个进程&#xff0c;通过fork函数&#xff0c;我们可以通过代码的形式从一个进程中创建一个进程&#xff0c;新进程为子进程&#xff0c;原进程为父进程&#xff0c;子进程在创建时&#xff0c;会与…

LabVIEW智能降噪系统

LabVIEW智能降噪系统 随着噪声污染问题的日益严重&#xff0c;寻找有效的降噪技术变得尤为关键。介绍了一种基于LabVIEW平台开发的智能降噪系统&#xff0c;该系统能够实时采集环境噪声&#xff0c;并通过先进的信号处理技术实现主动降噪&#xff0c;从而有效改善生活和工作环…

Stable Diffusion 进阶教程 - 二次开发(制作您的文生图应用)

目录 1. 引言 2. 基于Rest API 开发 2.1 前置条件 2.2 代码实现 2.3 效果演示 2.4 常见错误 3. 总结 1. 引言 Stable Diffusion作为一种强大的文本到图像生成模型&#xff0c;已经在艺术、设计和创意领域引起了广泛的关注和应用。然而&#xff0c;对于许多开发者来说&#xff…