【玩转Linux】标准IO函数

news2024/10/3 10:43:52
  • (꒪ꇴ꒪ ),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

📢写在最后

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

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

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

相关文章

Emvirus: 基于 embedding 的神经网络来预测 human-virus PPIs【Biosafety and Health,2023】

研究背景&#xff1a; Human-virus PPIs 预测对于理解病毒感染机制、病毒防控等十分重要&#xff1b;大部分基于 machine-learning 预测 human-virus PPIs 的方法利用手动方法处理序列特征&#xff0c;包括统计学特征、系统发育图谱、理化性质等&#xff1b;本文作者提出了一个…

redis面试1

Redis基础面试题 1、为什么要使用Redis做缓存 缓存的好处 使用缓存的目的就是提升读写性能。而实际业务场景下&#xff0c;更多的是为了提升读性能&#xff0c;带来更好的性 能&#xff0c;带来更高的并发量。Redis 的读写性能比 Mysql 好的多&#xff0c;我们就可以把 Mysq…

探索APP开发的新趋势:人工智能和大数据的力量

随着5G技术的不断发展&#xff0c;人工智能和大数据将会更加广泛的应用于我们生活和工作中&#xff0c;作为 APP开发公司&#xff0c;应该及时的对新技术进行研发&#xff0c;进而更好的为用户服务。目前 APP开发已经不是传统的软件开发了&#xff0c;而是向移动互联网转型&…

完全背包相关题

class Solution { public:int dp[5005];int change(int amount, vector<int>& coins) {//dp[j]表示金额为j时的组合数dp[0]1;for(int i0;i<coins.size();i){for(int jcoins[i];j<amount;j){dp[j]dp[j-coins[i]];}}return dp[amount];} }; 题解&#xff1a;如果…

Pandas库:从入门到应用(四)--数学函数

一、测试数据 import numpy as np import pandas as pd## 5行3列 0到100的数据 df pd.DataFrame(datanp.random.randint(0, 100, size(5, 3))) df二、基础聚合函数 2.1、count()函数 df.count() # 统计每列的行数(非空),默认axis0 df.count(axis1) # 统计每行的列数(非空)…

mysql的主键选择

一.没有定义主键有什么问题 如果定义了主键&#xff0c;那么InnoDB会使用主键作为聚簇索引如果没有定义主键&#xff0c;那么会使用第一非空的唯一索引&#xff08;NOT NULL and UNIQUE INDEX&#xff09;作为聚簇索引如果既没有主键也找不到合适的非空索引&#xff0c;那么In…

案例研究|DataEase助力亚加达智能医学实验室场景BI展示

深圳市亚加达信息技术有限公司&#xff08;以下简称为亚加达&#xff09;成立于2018年&#xff0c;是一家专注于医疗信息系统研发的高科技公司&#xff0c;隶属于亚辉龙集团。 亚加达深入理解医疗实验室业务和日常工作流程&#xff0c;通过物联网和大数据技术&#xff0c;基于…

数据库概述和DDL语句(学会并使用数据库day1)

数据库概述和DDL语句&#xff08;day1&#xff09; 一、数据库概述概念数据库的集中式控制有什么优点数据库分类mysql数据库mysql简介基本术语数据表的组成 数据库管理系统数据库管理系统、数据库和表的关系 二、SQL的概念三、SQL语句分类1、SQL语句被分为四大类2、MySQL的语法…

电脑上怎么进行pdf合并免费?看看这种方法

电脑上怎么进行pdf合并免费&#xff1f;在日常工作中&#xff0c;我们经常需要将多个PDF文档合并成一个文件&#xff0c;以方便管理和传输。如果你正在寻找一种简单易用的PDF合并工具&#xff0c;那么接下来就给大家介绍一种简单好用的合并方法。 【迅捷PDF转换器】是一款PDF转…

godot引擎c++源码深度解析系列一

许久没有使用c开发过项目了&#xff0c;如果按照此时单位的入职要求&#xff0c;必须拥有项目经验的话&#xff0c;那我就得回到十多年前&#xff0c;大学的时代&#xff0c;哪个时候真好&#xff0c;电脑没有这么普及&#xff0c;手机没有这么智能&#xff0c;网络没有这么发达…

01背包相关题

题解&#xff1a;dp[j]表示目标和为j时的最大组合种数 class Solution { public:int dp[1005];int findTargetSumWays(vector<int>& nums, int target) {int val;int sum0;for(int i0;i<nums.size();i){sumnums[i];}int wsumtarget;if(w%21){return 0;}else{valw…

重磅来袭 | 2023数字供应链安全大会邀请函(DSS 2023)

2023数字供应链安全大会&#xff08;DSS 2023&#xff09;将于8月10日在北京国家会议中心隆重开幕。本次大会由悬镜安全主办&#xff0c;ISC互联网安全大会组委会、中国软件评测中心&#xff08;工业和信息化部软件与集成电路促进中心&#xff09;、中国信息通信研究院云计算与…

基于IMX6ULL的智能车载终端项目(代码开源)

前言&#xff1a;本文为手把手教学智能车载终端项目&#xff08;LinuxQT&#xff09;&#xff0c;该项目是综合性非常强的 Linux 系列项目&#xff01;项目核心板使用 NXP 的 IMX6ULL 作为 CPU&#xff0c;整体实现了简化版本的车载终端功能需求。项目可以学习的点非常多&#…

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

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

leetcode 50. Pow(x, n)(x的n次方)

求x的n次方。 思路&#xff1a; 第一个想到的思路是x和它自己乘n次&#xff0c; 但是这样做会面临一些问题&#xff1a; 如果是简单的n很小的情况还好&#xff0c;但是可以看到n的取值横跨整个整数范围&#xff0c; 如果n非常大&#xff0c;一次一次乘x效率低是其一。 一般来…

十、数据结构——链式队列

数据结构中的链式队列 目录 一、链式队列的定义 二、链式队列的实现 三、链式队列的基本操作 ①初始化 ②判空 ③入队 ④出队 ⑤获取长度 ⑥打印 四、循环队列的应用 五、总结 六、全部代码 七、结果 在数据结构中&#xff0c;队列&#xff08;Queue&#xff09;是一种常见…

【MySQL】存储引擎(六)

&#x1f697;MySQL学习第六站~ &#x1f6a9;本文已收录至专栏&#xff1a;MySQL通关路 ❤️文末附全文思维导图&#xff0c;感谢各位点赞收藏支持~ 一.引入 大家可能没有听说过存储引擎&#xff0c;但是一定听过引擎这个词&#xff0c;引擎就是发动机&#xff0c;是一个机器…

PCB封装设计指导(十五)验证封装的正确性

PCB封装设计指导(十五)验证封装的正确性 封装建立好之后,我们需要验证封装是否能够正常的放入PCB文件中,最好最直接的办法就是直接放入PCB中来验证。 具体操作如下 任意新建一个空白的PCB文件点击File 选择NEW

搭建关键字驱动自动化测试框架

前言 上篇文章我们已经了解到了数据驱动自动化测试框架是如何构建和驱动测试的&#xff01;那么这篇文章我们将了解关键字驱动测试又是如何驱动自动化测试完成整个测试过程的。关键字驱动框架是一种功能自动化测试框架&#xff0c;它也被称为表格驱动测试或者基于动作字的测试…

一站式解决方案:Qt 跨平台开发灵活可靠

Qt 是一种跨平台开发工具&#xff0c;为开发者提供了一站式解决方案。无论您的项目目标是 Windows、Linux、macOS、嵌入式系统还是移动平台&#xff0c;Qt 都能胜任。这种跨平台的特性不仅节省开支&#xff0c;还推动了战略的快速落地。 适用范围广泛&#xff1a;Qt 可在多种操…