【玩转Linux】标准IO函数

  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
  • 快上🚘,一起学习!
  • 送给读者的一句鸡汤🤔:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏

标准IO函数

        标准IO函数是C语言标准库提供的一组用于输入和输出的函数,通常是以缓冲区为基础实现

【玩转Linux】标准io缓冲区的操作_祐言QAQ的博客-CSDN博客

的,可以提高程序的性能和效率。标准IO函数还可以通过文件指针操作文件,今天主要来学习一些常见的标准IO函数以及通过文件指针操作文件

1.fopen() / fclose()     

(1)功能:
        fopen():打开一个文件,返回一个文件指针,用于后续对文件的读写操作。
        fclose():关闭一个已打开的文件,释放相关资源。
(2)头文件:
        fopen()和fclose()函数需要包含头文件 <stdio.h>。
(3)原型:
        fopen():FILE *fopen(const char *filename, const char *mode);
        fclose():int fclose(FILE *stream);

(4)返回值:

  • fopen():如果文件打开成功,返回指向该文件的文件指针;如果打开失败,返回 NULL
  • fclose():成功关闭文件返回0,关闭失败返回非零值。

(5)示例:

FILE* fp = fopen("example.txt", "r");  // 以只读方式打开文件
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 读取文件内容
char buffer[10] = "hello";
fgets(buffer, 10, fp);
printf("文件内容:%s\n", buffer);
fclose(fp);  // 关闭文件

        想必大家看到这个例子也很懵,在fopen函数中的这个“r”是什么,其实这是打开文件的模式(mode),它一共有六种,分别是:

2.fgetc()和getc()和getchar(),以及fputc()和putc()和putchar()    

(1)功能:
        fgetc():从文件中读取一个字符。
        getc():从文件中读取一个字符。
        getchar():从标准输入中读取一个字符。
        fputc():将一个字符写入文件。
        putc():将一个字符写入文件。
        putchar():将一个字符写入标准输出。
(2)头文件:
        上述函数需要包含头文件 <stdio.h>。
(3)原型:
        fgetc():int fgetc(FILE *stream);
        getc():int getc(FILE *stream);
        getchar():int getchar(void);
        fputc():int fputc(int ch, FILE *stream);
        putc():int putc(int ch, FILE *stream);
        putchar():int putchar(int ch);

值得注意的是:

fgetc()是函数
getc()是宏//getc(stdin)等同于getchar()
stream:己经打开的文件流
getchar()只能从标准输入流(键盘)获取一个字符,getc()和fgetc()可以自定义从文件流读取一个字符

fputc()是函数
putc()是宏//putc('a',stdout)等同于putchar('a')
stream:已经打开的文件流
putchar()只能从标准输入流(键盘)获取一个字符,getc()和fgetc()可以自定义从文件流读取一个字符

(4)返回值

  • fgetc()getc()getchar()返回读取的字符的ASCII码值。
  • fputc()putc()putchar()返回写入的字符的ASCII码值。

(5)示例:  

FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 读取文件内容并输出
int c;
while ((c = fgetc(fp)) != EOF) {
    putchar(c);
}
fclose(fp);

FILE* fp2 = fopen("output.txt", "w");
if (fp2 == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 向文件中写入数据
fputc('H', fp2);
fputc('e', fp2);
fputc('l', fp2);
fputc('l', fp2);
fputc('o', fp2);
fclose(fp2);

3.fgets()/gets()/fputs()/puts()  

(1)功能:
    fgets():从文件中读取一行字符。
    gets():从标准输入中读取一行字符。
    fputs():将一行字符写入文件。
    puts():将一行字符写入标准输出。
(2)头文件:
    上述函数需要包含头文件 <stdio.h>。
(3)原型:
    char *fgets(char *str, int n, FILE *stream);
    char *gets(char *str);
    int fputs(const char *str, FILE *stream);
    int puts(const char *str);
(4)返回值:
    fgets():成功读取字符返回 str 的地址;读取失败或到达文件末尾返回 NULL。
    gets():成功读取字符返回 str 的地址;读取失败或到达文件末尾返回 NULL。
    fputs():成功写入字符返回非负值;写入失败返回 EOF。
    puts():成功写入字符返回非负值;写入失败返回 EOF。

(5)示例:

	// 打开一个文件
	FILE *fp = fopen("1.txt", "r+");	//以读写打开文件,但是要求文件必须存在
	if(fp == NULL)
	{
		perror("fopen() fail");
		exit(errno);
	}
	
	// 从文件中读取一个字符
	int ch = fgetc(fp);
	printf("ch = %c\n", ch);
	ch = getc(fp);
	printf("ch = %c\n", ch);
	
	getchar();	//默认从标准输入读取 getc(stdin);
FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 读取文件内容并输出
char buffer[100];
while (fgets(buffer, 100, fp) != NULL) {
    printf("%s", buffer);
}
fclose(fp);

FILE* fp2 = fopen("output.txt", "w");
if (fp2 == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 向文件中写入数据
fputs("Hello, world!\n", fp2);
fputs("This is a test.\n", fp2);
fclose(fp2);
    FILE *fp = fopen("1.txt", "r+");    // 以读写打开文件,要求文件必须存在
    if (fp == NULL) {
        perror("fopen() fail");
        exit(errno);
    }

    // 从文件中读取一个字符
    int ch = 'A';
    fputc(ch, fp);
    putc('B', fp);

    // 将文件指针移动到文件开头
    fseek(fp, 0, SEEK_SET);

    // 从文件中读取一个字符并打印到终端
    int read_ch = fgetc(fp);
    putchar(read_ch);

    fclose(fp); // 关闭文件

    return 0;
}

值得注意的有以下几点:
        (1)fgets()跟fgetc()一样,当其返回NULL时并不能确定究竟是达到文件末尾还是碰到错误,需要用feof()/ferror()来进一步判断。
       (2)fgets()每次读取至多不超过size个字节的一行,所谓“一行”即数据至多包含一个换行符'\n'。
        (3)gts()是一个已经过时的接口,因为他没有指定自定义缓冲区s的大小,这样很容易造成缓冲区溢出,导致程序段访问错误。
        (4)fgets()和fputs(),gets()和puts()一般成对使用,鉴于gets()的不安全性,一般建议使用前者。

4.feof()/ferror()   

功能:
    feof():检查文件流的文件结束标志,判断是否已经读取到文件末尾。
    ferror():检查文件流的错误标志,判断文件读取是否出错。
头文件:
    上述函数需要包含头文件 <stdio.h>。
原型:
    feof():int feof(FILE *stream);
    ferror():int ferror(FILE *stream);
返回值:
    feof():如果到达文件末尾,返回非零值(true);否则返回0(false)。
    ferror():如果文件读取出错,返回非零值(true);否则返回0(false)。

示例:

	// 打开一个文件
	FILE *fp = fopen("1.txt", "a+");	//以读写打开文件,但是要求文件必须存在
	if(fp == NULL)
	{
		perror("fopen() fail");
		exit(errno);
	}
	
	while(1)
	{
		int ch = fgetc(fp);
		if(ch == EOF)
		{
			if(feof(fp))	//为真,说明文件读到末尾
			{
				printf("文件已读完\n");
				break;
			}
			if(ferror(fp))		//为真,说明文件读取出错
			{
				perror("fgetc() fail");
				exit(errno);
			}
		}
		
		// 输出到屏幕
		printf("%c\n", ch);
	}
	
	// 关闭文件
	fclose(fp);

  5.fread(/fwrite()    

功能:
    fread():从文件中读取一段数据。
    fwrite():将一段数据写入文件。
头文件:
    上述函数需要包含头文件 <stdio.h>。
原型:
    size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:
    fread():返回实际成功读取的数据项数量,如果出错或到达文件末尾,返回值可能小于 nmemb。
    fwrite():返回实际成功写入的数据项数量,如果出错,返回值可能小于 nmemb。
示例:

struct student {
    char name[20];
    int age;
};

// 写入结构体数据到文件中
struct student s1 = {"Tom", 18};
FILE* fp = fopen("example.bin", "wb");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fwrite(&s1, sizeof(struct student), 1, fp);
fclose(fp);

// 从文件中读取结构体数据
struct student s2;
fp = fopen("example.bin", "rb");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fread(&s2, sizeof(struct student), 1, fp);
printf("姓名:%s,年龄:%d\n", s2.name, s2.age);
fclose(fp);

6.fseek()/ftell()/rewind 

功能:
    fseek():在文件中定位指针的位置,用于设置文件指针的位置。
    ftell():获取文件指针当前位置的偏移量。
    rewind():将文件指针重新定位到文件的起始位置。
头文件:
    上述函数需要包含头文件 <stdio.h>。
原型:
    int fseek(FILE *stream, long offset, int whence);
    long ftell(FILE *stream);
    void rewind(FILE *stream);
返回值:
    fseek():成功定位文件指针返回0,失败返回非零值。
    ftell():返回当前位置的偏移量。如果出错,返回 ftell() 出错的标识值 (-1)。
    rewind():无返回值。

示例:

FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 获取文件大小
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
printf("文件大小:%ld\n", size);
// 将文件指针移回文件开头
rewind(fp);
// 读取文件内容并输出
char buffer[100];
while (fgets(buffer, 100, fp) != NULL) {
    printf("%s", buffer);
}
fclose(fp);

7.printf()/fprintf()/sprintf()/snprintf()/scanf()/fscanf()/sscanf()

功能:
    printf():将格式化的数据输出到标准输出。
    fprintf():将格式化的数据输出到指定文件。
    sprintf():将格式化的数据输出到字符数组。
    snprintf():格式化数据输出到字符数组,并限制输出的字符数量。
    scanf():从标准输入读取格式化数据。
    fscanf():从指定文件读取格式化数据。
    sscanf():从字符数组读取格式化数据。
头文件:
上述函数需要包含头文件 <stdio.h>。
原型:
    int printf(const char *format, ...);
    int fprintf(FILE *stream, const char *format, ...);
    int sprintf(char *str, const char *format, ...);
    int snprintf(char *str, size_t size, const char *format, ...);
    int scanf(const char *format, ...);
    int fscanf(FILE *stream, const char *format, ...);
    int sscanf(const char *str, const char *format, ...);
返回值:
    printf():成功打印字符数。
    fprintf():成功写入字符数,失败返回负值。
    sprintf():成功写入字符数。
    snprintf():成功写入字符数(不包括末尾的空字符),如果截断输出返回欲写入的字符数。
    scanf():成功读取的参数个数。
    fscanf():成功读取的参数个数。
    sscanf():成功读取的参数个数。

示例:

// 格式化输出数据到标准输出设备
int num = 123;
printf("数字:%d\n", num);

// 格式化输出数据到文件
FILE* fp = fopen("output.txt", "w");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fprintf(fp, "数字:%d\n", num);
fclose(fp);

// 将格式化数据写入字符串中
char str[20];
sprintf(str, "数字:%d\n", num);
printf("%s", str);

// 将格式化数据写入指定长度的字符串中
char str2[10];
snprintf(str2, 10, "数字:%d\n", num);
printf("%s", str2);

// 从标准输入设备读取数据
int num2;
printf("请输入一个数字:");
scanf("%d", &num2);
printf("输入的数字:%d\n", num2);

// 从文件中读取数据
fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fscanf(fp, "数字:%d", &num2);
printf("从文件中读取的数字:%d\n", num2);
fclose(fp);

// 从字符串中读取数据
char str3[20] = "数字:456";
sscanf(str3, "数字:%d", &num2);
printf("从字符串中读取的数字:%d\n", num2);

关于格式控制符的一些解释:

格式控制符用于指定数据的输出格式。以下是常见的格式控制符:

整数类型:

        %d:有符号十进制整数
        %u:无符号十进制整数
        %o:无符号八进制整数
        %x:无符号十六进制整数(小写字母)
        %X:无符号十六进制整数(大写字母)


浮点数类型:

        %f:浮点数(以小数形式输出)
        %e:浮点数的指数表示(科学计数法,小写字母)
        %E:浮点数的指数表示(科学计数法,大写字母)
        %g:根据实际值自动选择%e或%f格式输出


字符类型:

        %c:字符
        %s:字符串


指针类型:

        %p:指针的地址值(以十六进制输出)


布尔类型:

        %d 或 %i:整数输出(0表示假,非零表示真)


特殊控制符:

        %%:输出百分号符号 %


        这些格式控制符可以用于 printf()、fprintf()、sprintf()、snprintf() 等输出函数,根据需要选择适合的格式控制符进行数据输出。

        

        更多C语言Linux系统相关文章,关注专栏:

   手撕C语言

            玩转linux

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为数通HCIP-OSPF路由计算

路由协议 作用&#xff1a;用于路由设备学习非直连路由&#xff1b; 动态路由协议&#xff1a;使路由设备自动学习到非直连路由&#xff1b; 分类&#xff1a; 按照算法分类&#xff1a; 1、距离矢量路由协议&#xff1b;&#xff08;RIP、BGP&#xff09; 只交互路由信息…

什么是Redis?

什么是Redis 什么是Redis一、特性1. 支持多种数据结构2. 读/写速度快&#xff0c;性能高。3. 支持持久化。4. 实现高可用主从复制&#xff0c;主节点做数据副本。5. 实现分布式集群和高可用。 二、基本数据类型string&#xff08;字符串&#xff09;list(双向链表)set(集合)zse…

PostgreSQL数据库动态共享内存管理器——Dynamic shared memory areas

dsm.c提供的功能允许创建后端进程间共享的共享内存段。DSA利用多个DSM段提供共享内存heap&#xff1b;DSA可以利用已经存在的共享内存&#xff08;DSM段&#xff09;也可以创建额外的DSM段。和系统heap使用指针不同的是&#xff0c;DSA提供伪指针&#xff0c;可以转换为backend…

Java的第十三篇文章——JAVA多线程

目录 学习目标 1. 线程的基本概念 1.1 进程 1.2 线程 2. Java实现线程程序 2.1 java.lang.Thread类 2.2 线程的内存图 2.3 Thread类的方法 3. Java实现线程程序 3.1 java.lang.Runnable接口 3.2 实现接口的好处 4. 线程安全 4.1 售票例子 4.2 同步代码块 4.3 同…

为什么视频画质会变差,如何提升视频画质清晰度。

在数字时代&#xff0c;视频已经成为我们生活中不可或缺的一部分。然而&#xff0c;随着视频的传输和处理过程中的多次压缩&#xff0c;画质损失逐渐凸显&#xff0c;影响了我们对影像的真实感受。为了让视频画质更加清晰、逼真&#xff0c;我们需要采取一些措施来保护和修复视…

物联网网关模块可以带几台plc设备吗?可以接几个modbus设备?

随着物联网技术的快速发展&#xff0c;物联网网关模块已经成为了实现物联网应用的重要工具。很多客户在选择物联网网关模块时想了解物联网网关模块的设备接入能力&#xff0c;一个物联网网关模块可以带几台PLC设备&#xff1f;可以接几个Modbus设备&#xff1f; 物联网网关模块…

基于Jquery EasyUI JSZip FileSaver的简单使用

一、前言 在前端的项目开发中 &#xff0c;下载文件压缩包是很重要的一个环节&#xff0c;那么怎么下载多个文件并压缩成ZIP下载呢&#xff1f; 二、使用步骤 1、引用库 <script type"text/javascript" src"~/Scripts/comm/jszip.min.js" ></…

【设计模式——学习笔记】23种设计模式——适配器模式Adapter(原理讲解+应用场景介绍+案例介绍+Java代码实现)

介绍 生活中的案例 不同国家的插座不同&#xff0c;出国旅游充电器不能直接使用&#xff0c;可以通过使用多功能转换插头来辅助使用 基础介绍 适配器模式将某个类的接口转换成客户端期望的另一个接口表示&#xff0c;主的目的是兼容性&#xff0c;让原本因接口不匹配不能一起…

JVM理论(六)执行引擎--垃圾回收

概述 垃圾: 指的是在运行程序中没有任何指针指向的对象垃圾回收目的: 为了及时清理空间使得程序可以正常运行垃圾回收机制: JVM采取的是自动内存管理,即JVM负责对象的创建以及回收,将程序员从繁重的内存管理释放出来,更加专注业务的开发垃圾回收区域: 频繁收集Young区(新生代)…

【面试】 redis击穿现象?如何防止击穿?

文章目录 背景击穿案例解决方案:通过synchronized双重检查机制&#xff1a;某个key只让一个线程查询&#xff0c;阻塞其它线程设置value永不过期&#xff08;设置热点数据永不过期&#xff09;使用互斥锁(mutex key) 背景 大家都知道,计算机的瓶颈之一就是IO,为了解决内存与磁…

【深度学习】yolov 图片训练的时候的遇到的warning: corrupt JPEG restored and saved

报错原因 是图片在dataset.py 走验证时报的错误。 if im.format.lower() in (jpg, jpeg):with open(im_file, rb) as f:f.seek(-2, 2)if f.read() ! b\xff\xd9: # corrupt JPEGImageOps.exif_transpose(Image.open(im_file)).save(im_file, JPEG, subsampling0, quality100)m…

数据结构——顺序表

即使你内心没有一尊明月&#xff0c;也要给自己留下一方皎洁 文章目录 什么是顺序表 顺序表的实现 顺序表内部基础设置 结构体数据类型重定义 顺序表结构定义 顺序表空间初始化及扩容设置 顺序表空间的初始化及销毁 顺序表的扩容 顺序表基本功能 尾插尾删 头插头删…

css设置八等分圆

现需要上图样式的布局&#xff0c;我通过两张向右方的图片&#xff0c;通过定位和旋转完成了布局。 问题&#xff1a; 由于是通过旋转获取到的样式&#xff0c;实际的盒子是一个长方形&#xff0c;当鼠标移入对应的箭头时选中的可能是其他盒子&#xff0c;如第一张设计稿可以看…

10.函数

10.1为什么需要函数 ●函数: function&#xff0c;是被设计为 执行特定任务的代码块 ●作用&#xff1a; 精简代码方便复用&#xff08;实现代码复用&#xff0c;提高开发效率&#xff09; 比如我们前面使用的alert()、prompt() 和console.log()都是一些js函数&#xff0c;只不…

编译/反编译

1.Android APK 1.软件 1.apktool 1.作用&#xff1a;反编译apk或重新打包apk 2.dex2jar 1.作用&#xff1a;将Android的可执行文件.dex转换为.jar 3.jd-gui 1.作用&#xff1a;方便阅读jar文件的代码工具 2.步骤 1.通过apktool将apk软件反编译2.使用dex2jar将classes.dex文件转…

(十五) InfluxDB服务进程参数(influxd命令的用法)

以下内容来自 尚硅谷&#xff0c;写这一系列的文章&#xff0c;主要是为了方便后续自己的查看&#xff0c;不用带着个PDF找来找去的&#xff0c;太麻烦&#xff01; 第 15 章 InfluxDB服务进程参数&#xff08;influxd命令的用法&#xff09; 15.1 influxd命令罗列 1、我们的…

Django 图书管理系统

一、功能及页面设计 二、页面展示 (1)首页 (2)注册 (3)登录 (4)普通用户登录 4.1查看图书页面 4.2查看图书详情页 4.3修改密码 (5)管理员登录 5.1添加图书 5.2添加图片 三、代码展示 因为代码太多不好一个个展示 所以需要源码的小伙伴可以找我要代码 感谢三连支持&#xff0…

【C++】多态原理剖析,Visual Studio开发人员工具使用查看类结构cl /d1 reportSingleClassLayout

author&#xff1a;&Carlton tag&#xff1a;C topic&#xff1a;【C】多态原理剖析&#xff0c;Visual Studio开发人员工具使用查看类结构cl /d1 reportSingleClassLayout website:黑马程序员C tool&#xff1a;Visual Studio 2019 date&#xff1a;2023年7月24日 目…

最快桌面UI:Siticone Desktop UI 2.1.1 cRACK

富图尔主义控制 80 多个 .NET UI 组件和控件 现代未来 UI/UX 组件 为 Visual Studio 开发做好准备 无限的免费产品支持案例 超轻量和快速性能 广泛可定制和主题化 低资源消耗和占地面积 免版税开发和部署 NET 的最佳 UI 和 UX 库 从最好的图书馆探索无缝流畅的体验 使…

二、SQL-5.DQL-9.执行顺序

一、案例&#xff1a; 查询年龄大于15的员工的姓名、年龄&#xff0c;并根据年龄进行升序排序 select name, age from emp where age > 15 order by age asc; 先执行①from&#xff08;定义emp的别名为e&#xff09;&#xff0c;再执行②where&#xff08;调用别名e&…