22. C语言 输入与输出详解
本章目录:
- 前言
- 1. 输入输出的基础概念
- 1.1 标准输入输出流
- 1.2 输入输出函数
- 2. 格式化输出与输入
- 2.1 使用 `printf()` 进行输出
- 示例 1: 输出字符串
- 示例 2: 输出整数
- 示例 3: 输出浮点数
- 2.2 使用 `scanf()` 进行输入
- 示例 4: 读取整数和字符
- 改进方案:使用`getchar()`清理缓冲区
- 使用 `scanf()` 读取字符串
- 3. 其他输入输出函数
- 3.1 `getchar()` 和 `putchar()`
- 示例 5: 使用 `getchar()` 和 `putchar()`
- 3.2 `gets()` 和 `puts()`
- 示例 6: 使用 `gets()` 和 `puts()`
- 3.3 更安全的替代方法:`fgets()`
- 总结
前言
在编程中,输入与输出(I/O)是与用户交互的最基本方式之一。C语言作为一种面向过程的语言,其标准库提供了一系列的函数来帮助我们从键盘读取数据和将数据输出到屏幕或文件中。理解这些输入输出操作的机制对于编写高效、健壮的程序至关重要。本文将详细探讨C语言中的输入输出函数,并给出一些实际的代码示例及技巧,帮助你深入理解输入输出的工作原理。
1. 输入输出的基础概念
1.1 标准输入输出流
C语言将所有的外部设备(包括键盘、屏幕、文件等)都看作文件。因此,C语言的输入输出操作实际上是通过文件流(file streams)来实现的。标准库中为我们提供了三个标准流,这些流在程序启动时自动打开:
- 标准输入(stdin):通常连接到键盘,接受用户输入。
- 标准输出(stdout):通常连接到屏幕,用于输出程序结果。
- 标准错误(stderr):通常连接到屏幕,专门用于输出错误信息。
在C语言中,文件指针是访问这些流的句柄。程序通过这些文件指针与外部设备进行交互。
1.2 输入输出函数
C语言提供了多个函数来实现输入输出操作,其中最常用的两个函数是 printf()
和 scanf()
。
printf()
:用于格式化输出,将数据打印到屏幕。scanf()
:用于格式化输入,从键盘读取数据。
这两个函数都支持格式化操作,允许程序员指定数据的显示或读取方式。
2. 格式化输出与输入
2.1 使用 printf()
进行输出
printf()
函数是C语言中最常用的输出函数。它允许你以多种格式将数据输出到标准输出流(通常是屏幕)。它的基本语法如下:
int printf(const char *format, ...);
其中,format
是一个包含格式控制的字符串,可以包括普通文本和格式占位符(例如 %d
、%f
等),这些占位符用于指定输出的变量类型。
示例 1: 输出字符串
#include <stdio.h>int main() {printf("Hello, C World!\n");return 0;
}
输出:
Hello, C World!
示例 2: 输出整数
#include <stdio.h>int main() {int number = 42;printf("The number is: %d\n", number);return 0;
}
输出:
The number is: 42
在这个例子中,%d
是格式说明符,用来输出一个整数类型的变量。
示例 3: 输出浮点数
#include <stdio.h>int main() {float pi = 3.14159;printf("Pi is approximately: %.2f\n", pi);return 0;
}
输出:
Pi is approximately: 3.14
2.2 使用 scanf()
进行输入
scanf()
函数用于从标准输入流(通常是键盘)读取数据,并将其存储到变量中。它的基本语法如下:
int scanf(const char *format, ...);
示例 4: 读取整数和字符
#include <stdio.h>int main() {int number;char character;printf("Enter an integer and a character: ");scanf("%d%c", &number, &character);printf("You entered: %d and %c\n", number, character);return 0;
}
问题:为什么读取字符时会有问题?
当你运行上述代码时,输入格式如 5a
可能会导致不符合预期的结果。问题出在scanf()
函数中,读取整数后,scanf()
并不会清空输入缓冲区,换行符或空格可能会被意外读取为字符。因此,字符变量character
会接收到一个额外的换行符(\n
)。
改进方案:使用getchar()
清理缓冲区
为了解决这个问题,可以使用getchar()
来读取并清除输入缓冲区中的换行符或空格:
#include <stdio.h>int main() {int number;char character;printf("Enter an integer and a character: ");scanf("%d", &number);while ((character = getchar()) == ' ' || character == '\n'); // 清理缓冲区scanf("%c", &character); // 正常读取字符printf("You entered: %d and %c\n", number, character);return 0;
}
这样做可以确保在读取字符时没有意外的换行符或空格。
使用 scanf()
读取字符串
#include <stdio.h>int main() {char name[50];printf("Enter your name: ");scanf("%s", name); // 不会读取空格后的部分printf("Hello, %s!\n", name);return 0;
}
输出:
Enter your name: Alice
Hello, Alice!
需要注意的是,scanf("%s", name)
会在遇到空格时停止读取,因此只能读取一个单词。如果你需要读取包含空格的整行文本,可以使用 fgets()
。
3. 其他输入输出函数
3.1 getchar()
和 putchar()
getchar()
:从标准输入流中读取下一个字符,并返回该字符的ASCII值。putchar()
:将一个字符输出到标准输出流。
示例 5: 使用 getchar()
和 putchar()
#include <stdio.h>int main() {char c;printf("Enter a character: ");c = getchar();printf("You entered: ");putchar(c);printf("\n");return 0;
}
输出:
Enter a character: A
You entered: A
3.2 gets()
和 puts()
gets()
:读取一行文本(包括空格)直到遇到换行符为止。(已废弃)puts()
:输出一个字符串并自动添加换行符。
示例 6: 使用 gets()
和 puts()
#include <stdio.h>int main() {char str[100];printf("Enter a string: ");gets(str); // 注意:此函数已被废弃,不推荐使用puts("You entered:");puts(str);return 0;
}
输出:
Enter a string: Hello World
You entered:
Hello World
3.3 更安全的替代方法:fgets()
由于 gets()
存在安全隐患(无法防止缓冲区溢出),建议使用 fgets()
替代它。
#include <stdio.h>int main() {char str[100];printf("Enter a string: ");fgets(str, sizeof(str), stdin); // 安全读取一行输入printf("You entered: ");puts(str);return 0;
}
总结
- 使用
scanf()
时要小心缓冲区问题,例如处理换行符和空格时。可以通过使用getchar()
或scanf()
格式控制来避免这些问题。 - 避免使用
gets()
,因为它无法防止缓冲区溢出。推荐使用fgets()
作为替代方案。 - 理解格式化输入输出的工作原理,如
%d
、%f
、%s
等格式符,能帮助你更精确地控制输入输出。
通过掌握这些输入输出的技巧,你可以编写更加健壮、易用的程序,避免一些常见的错误和安全隐患。希望本文能为你提供清晰的理解,并帮助你在C语言的学习旅程中走得更远。
相关文章:
22. C语言 输入与输出详解
本章目录: 前言1. 输入输出的基础概念1.1 标准输入输出流1.2 输入输出函数 2. 格式化输出与输入2.1 使用 printf() 进行输出示例 1: 输出字符串示例 2: 输出整数示例 3: 输出浮点数 2.2 使用 scanf() 进行输入示例 4: 读取整数和字符改进方案:使用getchar()清理缓冲…...

WPF实战案例 | C# WPF实现计算器源码
WPF实战案例 | C# WPF实现计算器源码 一、设计来源计算器应用程序讲解1.1 主界面1.2 计算界面 二、效果和源码2.1 界面设计(XAML)2.2 代码逻辑(C#)2.3 实现步骤总结 源码下载更多优质源码分享 作者:xcLeigh 文章地址&a…...

AutoGen入门——快速实现多角色、多用户、多智能体对话系统
1.前言 如https://github.com/microsoft/autogen所述,autogen是一多智能体的框架,属于微软旗下的产品。 依靠AutoGen我们可以快速构建出一个多智能体应用,以满足我们各种业务场景。 本文将以几个示例场景,使用AutoGen快速构建出…...

LeetCode 热题 100_全排列(55_46_中等_C++)(递归(回溯))
LeetCode 热题 100_两数之和(55_46) 题目描述:输入输出样例:题解:解题思路:思路一(递归(回溯)): 代码实现代码实现(思路一(…...

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(1.标准版)
问题 项目里使用了 AzureBlob 存储了用户上传的各种资源文件,近期 AzureBlob 的流量费用增长很快,想通过分析Blob的日志,获取一些可用的信息,所以有了这个需求:将存储账户的日志(读写,审计&…...
pthread_exit函数
pthread_exit 是 POSIX 线程库(pthread)中的一个函数,用于显式地终止调用线程。与 exit 函数不同,pthread_exit 仅影响调用它的线程,而不是整个进程。使用 pthread_exit 可以确保线程在退出时能够正确地释放线程相关的…...

1月21日星期二今日早报简报微语报早读
1月21日星期二,农历腊月廿二,早报#微语早读。 1、多地官宣:2025年可有序、限时或在限定区域燃放烟花爆竹; 2、TikTok恢复在美服务;特朗普提出继续运营TikTok方案,外交部:若涉及收购中国企业应…...

【2024年终总结】我与CSDN的一年
👉作者主页:心疼你的一切 👉作者简介:大家好,我是心疼你的一切。Unity3D领域新星创作者🏆,华为云享专家🏆 👉记得点赞 👍 收藏 ⭐爱你们,么么哒 文章目录 …...

openssl 正确生成v3带SAN的证书
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...

Golang Gin系列-5:数据模型和数据库
在这篇Gin教程的博客中,我们将探索如何将模型和数据库与Gin框架无缝集成,使你能够构建健壮且可扩展的web应用程序。通过利用流行的库并遵循最佳实践,你将学习如何定义模型、建立数据库连接、执行CRUD操作以及确保基于gin的项目中的数据完整性…...

比简单工厂更好的 - 工厂方法模式(Factory Method Pattern)
工厂方法模式(Factory Method Pattern) 工厂方法模式(Factory Method Pattern)工厂方法模式(Factory Method Pattern)概述工厂方法模式(Factory Method Pattern)结构图工厂方法模式&…...

分布式搜索引擎02
1. DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1. DSL查询分类 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,…...

阿里云安装mikrotik7配置内网互通
阿里云近期推出了200M不限量机器,对于没有公网接入的中小企业可以借助这个机器对多地分支机构进行内网互通。目前已经有很多机构用这个搞跨云k8s,跨云集群了。 mikrotik作为一个商用的软件,操作性比一些开源的软件好用不少。 本文使用的网段为172.16.1…...

Docker网段和服务器ip冲突导致无法访问网络的解决方法
若宿主机所在网络的网段为172.[17-31].xx.xx,则会与Docker本身内部网络间出现冲突,此时需要重新配置Docker默认地址池 一:查看docker的默认网段 route 二:修改docker的默认网段 etc/docker/daemon.json文件增加修改网段信息 {…...

Kubernetes 集群中安装和配置 Kubernetes Dashboard
前言 上篇成功部署Kubernetes集群后,为了方便管理和监控集群资源,安装Kubernetes Dashboard显得尤为重要。Kubernetes Dashboard 是一个通用的、基于 Web 的 UI,旨在让用户轻松地部署容器化应用到 Kubernetes 集群,并对这些应用进…...
Android开发之Spinner
Android开发之Spinner 1. 概述2. Spinner3. 适配器3.1 ArrayAdapter3.2 SimpleAdapter 1. 概述 Android开发学习笔记。学习下拉框控件Spinner和适配器(数组适配器ArrayAdapter、简单适配器SimpleAdapter)的使用。 2. Spinner 下拉框控件,用…...

【c++继承篇】--继承之道:在C++的世界中编织血脉与传承
目录 引言 一、定义二、继承定义格式2.1定义格式2.2继承关系和访问限定符2.3继承后子类访问权限 三、基类和派生类赋值转换四、继承的作用域4.1同名变量4.2同名函数 五、派生类的默认成员构造函数5.1**构造函数调用顺序:**5.2**析构函数调用顺序:**5.3调…...

分布式系统通信解决方案:Netty 与 Protobuf 高效应用
分布式系统通信解决方案:Netty 与 Protobuf 高效应用 一、引言 在现代网络编程中,数据的编解码是系统设计的一个核心问题,特别是在高并发和低延迟的应用场景中,如何高效地序列化和传输数据对于系统的性能至关重要。随着分布式系…...

计算机网络 (54)系统安全:防火墙与入侵检测
前言 计算机网络系统安全是确保网络通信和数据不受未经授权访问、泄露、破坏或篡改的关键。防火墙和入侵检测系统(IDS)是维护网络系统安全的两大核心组件。 一、防火墙 定义与功能 防火墙是一种用来加强网络之间访问控制的特殊网络互联设备,它…...
stack底层实现细节
一、stack 和 queue 在 STL 中 stack 和 queue 已经不算是容器了,而是容器适配器,适配器模式也是常用的模式之一,体现在 stack 和 queue 中就是他们两个的实现不是单独写的,而是复用了前面合适的优秀的STL 容器的代码而实现的具有…...
python中使用高并发分布式队列库celery的那些坑
python中使用高并发分布式队列库celery的那些坑 🌟 简单理解🛠️ 核心功能🚀 工作机制📦 示例代码(使用 Redis 作为 broker)🔗 常见搭配📦 我的环境📦第一个问题…...
将 AI 解答转换为 Word 文档
相关说明 DeepSeek 风靡全球的2025年,估计好多人都已经试过了,对于理科老师而言,有一个使用痛点,就是如何将 AI 输出的 mathjax 格式的符号转化为我们经常使用的 mathtype 格式的,以下举例说明。 温馨提示࿱…...

asio之async_result
简介 async_result用来表示异步处理返回类型 async_result 是类模板 type:为类模板中声明的类型,对于不同的类型,可以使用类模板特例化,比如针对use_future...

【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix
【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix 文章目录 【航天远景 MapMatrix 精品教程】08 Pix4d空三成果导入MapMatrix一、资料准备1.去畸变影像2.相机文件3.外方位元素二、创建工程1.新建工程2.导入照片3.编辑相机文件4.编辑外方位元素文件,导入外方位元…...

mapbox高阶,PMTiles介绍,MBTiles、PMTiles对比,加载PMTiles文件
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️Fill面图层样式1.4 ☘️PMTiles介绍1.5…...
开发时如何通过Service暴露应用?ClusterIP、NodePort和LoadBalancer类型的使用场景分别是什么?
一、Service核心概念 Service通过标签选择器(Label Selector)关联Pod,为动态变化的Pod集合提供稳定的虚拟IP和DNS名称,主要解决: 服务发现负载均衡流量路由 二、Service类型详解 1. ClusterIP(默认类型…...

微信小程序一次性订阅封装
封装代码如下: export async function subscribeMessage(tmplIds: string[]): Promise<ISubscribeMessagePromise> {// 模板ID// 1、获取设置状态const settings (await wx.getSetting({ withSubscriptions: true })).subscriptionsSetting || {}console.log…...
深度解析新能源汽车结构与工作原理
一、核心系统架构 新能源汽车主要由三大核心系统构成: 电力驱动系统:包含永磁同步电机、电机控制器(MCU)及减速器,采用三合一集成设计实现轻量化。永磁同步电机通过电磁感应原理将电能转化为机械能,其效率可…...

SpringBoot整合MinIO实现文件上传
使用Spring Boot与JSP和MinIO(一个开源对象存储系统,兼容Amazon S3)进行集成,您可以创建一个Web应用来上传、存储和管理文件。以下是如何将Spring Boot、JSP和MinIO集成的基本步骤: 这个是minio正确启动界面 这个是min…...
斗地主游戏出牌逻辑用Python如何实现
在Python中实现斗地主的出牌逻辑需要结合游戏规则与数据结构设计,以下是核心实现思路和代码示例: 一、基础数据结构设计 1. 扑克牌表示 用类或字典表示每张牌的花色和点数,例如: class Card: def __init__(self, suit, rank): sel…...