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 容器的代码而实现的具有…...
OpenClaw技能安装失败全解析:从依赖冲突到网络问题的系统性解决方案
1. 项目概述:当技能“卡住”时,我们遇到了什么?最近在折腾OpenClaw这类开源AI助手平台时,不少朋友都踩进了同一个坑:从官方市场或者第三方渠道找到了心仪的技能(Skill),点击“安装”…...
Ventoy终极指南:一个U盘启动所有系统,告别重复格式化烦恼 [特殊字符]
Ventoy终极指南:一个U盘启动所有系统,告别重复格式化烦恼 😎 【免费下载链接】Ventoy A new bootable USB solution. 项目地址: https://gitcode.com/GitHub_Trending/ve/Ventoy 还在为每次安装系统都要重新制作启动盘而烦恼吗&#x…...
【CP-05】RTE运行时环境 - SWC的操作系统接口
CP-05_RTE运行时环境【CP-05】RTE运行时环境 - SWC的“操作系统接口”前言在AUTOSAR架构中,RTE(Runtime Environment,运行时环境)是一个常被提及却难以理解的概念。它像是应用层软件组件(SW-C)与底层基础软…...
户外实用|艾迪欧 R6000 测评 —— 户外 / 自驾 / 露营的通讯好搭档
户外出行,通讯工具的核心是稳定、清晰、耐用、续航久、功能全。艾迪欧 R6000 作为一款兼顾专业与户外的 DMR 对讲机,全频段覆盖、双模通讯、自定义功能、长续航,完美适配自驾、露营、登山、越野等户外场景,是户外爱好者的靠谱通讯…...
从BUG()到panic:深入Linux 5.4内核,看异常处理如何层层递进
从BUG()到panic:Linux内核异常处理的防御体系全解析当你在深夜调试一个内核模块时,突然屏幕刷出一串红色警告——这可能是每个Linux内核开发者都经历过的噩梦时刻。但你是否想过,从第一行警告出现到系统完全崩溃,内核究竟经历了怎…...
中兴光猫终极管理指南:解锁工厂模式与Telnet权限的实战教程
中兴光猫终极管理指南:解锁工厂模式与Telnet权限的实战教程 【免费下载链接】zteOnu A tool that can open ZTE onu device factory mode 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 掌握中兴光猫的设备管理和权限获取能力是网络管理员和技术爱好者…...
AI圈内火热的Agent、MCP、Skill、CLI是啥?用装修房子讲透,看完秒懂
本文用装修房子的比喻,详细解释了AI领域的四个核心概念:Agent如同会自主规划任务的私人助理;MCP是AI与外部工具数据的统一接口,类似USB-C;Skill是指导AI按标准操作执行的手册;CLI则是不依赖图形界面的命令行…...
Unity塔防底层架构:ScriptableObject驱动的数据契约设计
1. 这不是“又一个塔防模板”,而是塔防开发的底层操作系统我第一次在Asset Store点开Tower Defense Toolkit 4(TDTK-4)的预览图时,下意识划走了——界面太“干净”了,没有炫酷的粒子特效演示,没有满屏飞舞的…...
CA-CFAR、GO-CFAR、SO-CFAR怎么选?一张图看懂三种恒虚警检测算法的适用场景与避坑指南
CA-CFAR、GO-CFAR、SO-CFAR工程选型指南:从算法原理到场景适配 雷达信号处理工程师常常面临一个经典难题:在复杂环境中如何选择合适的恒虚警检测算法?当海面杂波、多目标干扰或低信噪比条件同时出现时,CA、GO、SO三种CFAR变体的性…...
大模型测试新范式:Claude端到端验证的5层断言体系(语义一致性/上下文连贯性/安全边界/成本阈值/时序鲁棒性)
更多请点击: https://codechina.net 第一章:大模型测试新范式:Claude端到端验证的5层断言体系(语义一致性/上下文连贯性/安全边界/成本阈值/时序鲁棒性) 传统LLM测试常聚焦于准确率或BLEU等静态指标,而Cla…...
