玩转C语言:深入理解输入输出函数的奥秘
欢迎大家来到贝蒂大讲堂
养成好习惯,先赞后看哦~
所属专栏:C语言学习
贝蒂的主页:Betty‘s blog
1. 单字符输出函数
在C语言中有一个函数putchar专门负责输出单个字符,其语法如下:
头文件:#include<stdio.h>
声明:int putchar(int char)
- char -- 这是要被写入的字符。该字符以其对应的 int 值进行传递。
作用:把参数 char 指定的字符(一个无符号字符)写入到标准输出 stdout 中,也就是输出单个字符。
返回值:该函数以无符号 char 强制转换为 int 的形式返回写入的字符,如果发生错误则返回 EOF。
以下是对putchar的具体使用示例:
#include<stdio.h>
int main()
{
putchar('A');//输出字符A
putchar('1');//输出字符1
putchar('\106');//输出转义字符F
return 0;
}
输出结果:

2. 多字符输出函数
既然有单字符输出函数,那就自然有多字符输出函数——puts,其语法如下:
- 头文件:#include<stdio.h>
- 声明:int puts(const char *str)
- str -- 这是要被写入的 C 字符串。
- 作用:把一个字符串写入到标准输出 stdout,直到空字符,但不包括空字符。换行符会被追加到输出中。
- 返回值:如果成功,该函数返回一个非负值为字符串长度(包括末尾的 \0),如果发生错误则返回 EOF。
以下是对puts的具体使用示例:
int main()
{
puts("hello world\n");
puts("贝蒂来啦\n");
return 0;
}
输出结果:

3. 格式化输出函数
3.1 语法
介绍完单字符与多字符输出函数,下面我们将介绍格式化输出函数——printf,其语法如下:
- 头文件:#include<stdio.h>
- 声明:int printf(const char *format, ...)
- format -- 这是字符串,包含了要被写入到标准输出 stdout 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。
- 作用:将参数⽂本输出到屏幕
- 返回值:如果成功,则返回写入的字符总数,否则返回一个负数。
3.2 占位符
printf() 可以在输出⽂本中指定占位符。所谓“占位符”,就是这个位置可以⽤其他值代⼊。下表是常见的占位符:
| 占位符 | 含义 |
|---|---|
| %d | 以十进制形式输出整数 |
| %u | 以十进制形式输出无符号整数 |
| %x | 以十六进制形式输出整数(小写字母) |
| %X | 以十六进制形式输出整数(大写字母) |
| %o | 以八进制形式输出整数 |
| %f | 以浮点数形式输出实数 |
| %e | 以指数形式输出实数 |
| %g | 自动选择 %f 或 %e 输出实数 |
| %c | 输出单个字符 |
| %s | 输出字符串 |
| %p | 输出指针的地址 |
| %n | 输出已经输出的字符数 |
| %% | 输出百分号本身 |
以下是对printf的具体使用示例:
int main()
{
printf("%d\n", 5);//打印整型
printf("%f\n", 5.1);//打印浮点型
printf("%c\n", 'a');//打印字符
printf("%s\n", "betty");//打印字符串
printf("betty");//也可以这样打印字符串
return 0;
}
输出结果:

- printf() 参数与占位符是⼀⼀对应关系,如果有 n 个占位符, printf() 的参数就应该有 n +1 个(双引号内部也算一个)。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。
3.3 限定格式
(1) 限定宽度
printf() 允许限定占位符的最⼩宽度。以下是具体的实例:
int main()
{
printf("%4d\n", 123);
printf("%-4d\n", 123);
printf("%12f\n", 123.45);
return 0;
}

- 上⾯⽰例中, %4d 表⽰这个占位符的宽度至少为4位。如果不满4位,对应的值的前⾯会添加空格。输出的值默认是右对⻬,即输出内容前⾯会有空格;如果希望改成左对⻬,在输出内容后⾯添加空格,可以在占位符的 % 的后⾯插⼊⼀个 - 号。
- 对于⼩数,这个限定符会限制所有数字的最⼩显⽰宽度。上⾯⽰例中, %12f 表⽰输出的浮点数最少要占据12位。由于⼩数的默认显⽰精度是⼩数点后6位,所以 123.45 输出结果的头部会添加2个空格。
(2) 总是显示正负号
默认情况下, printf() 不对正数显示 + 号,只对负数显示 - 号。如果想让正数也输出 + 号,可以在占位符的 % 后⾯加⼀个 + 。
int main()
{
printf("%+d\n", 13);
printf("%+d\n", -13);
return 0;
}
(3) 限制小数位数
输出⼩数时,有时希望限定⼩数的位数。举例来说,希望⼩数点后⾯只保留两位,占位符可以写成 %.2f 。
#include <stdio.h>
int main()
{
printf("Number is %.2f\n", 0.5);//输出0.50
return 0;
}
- 这种写法也是可以与限定宽度结合使用的
(4) 限定字符串的输出
%s 占位符⽤来输出字符串,默认是全部输出。如果只想输出开头的部分,可以⽤ %.[m]s 指定输出的⻓度,其中 [m] 代表⼀个数字,表⽰所要输出的⻓度。
#include <stdio.h>
int main()
{
printf("%.5s", "hello world");
return 0;
}
输出结果:

(5) 限定值输入
最⼩宽度和⼩数位数这两个限定值,都可以⽤ ***** 代替,通过 printf() 的参数传⼊。
#include <stdio.h>
int main()
{
printf("%*.*f\n", 6, 2, 0.5);
return 0;
}// 等同于printf("%6.2f\n", 0.5);
3.4 printf的返回值
我们在前面介绍printf时候就已经了解过其返回值:如果成功,则返回写入的字符总数,否则返回一个负数。
下面就让我们通过下列两道题来加深理解:
(1) 题目一
int main()
{
int a = 43;
printf("%d\n", printf("%d", printf("%d", a)));//输出什么??
return 0;
}
- 首先肯定会执行最里面的printf("%d",43),在屏幕上打印出43。
- 然后执行printf("%d", printf("%d", 43)),相当于打印第一步printf的返回值,‘4’,‘3’有两个字符,所以返回值是2。
- 最后同理执行printf("%d", printf("%d", printf("%d", 43))),即打印第二步的‘2’返回值,一个字符,返回值为1。
- 所以屏幕上最后打印的就是4321。

(2) 题目二
int main()
{
printf("%d\n",printf("%d\n",printf("hello!\n"))); //输出??
return 0;
}https://s11.ax1x.com/2024/02/20/pFYxXCT.png
- 首先肯定会打印出hello!然后换行。
- 然后打印printf("%d\n",printf("hello!\n")),即第一步的返回值,需要注意是‘\n’是一个字符,所以返回值是7,换行。
- 最后打印printf("%d\n",printf("%d\n",printf("hello!\n"))),即第二步的返回值,格式化字符串的‘\n’也会算做一个字符,一共两个字符,所以最后打印出2。

4. 单字符输入函数
单字符输入函数——getchar,顾名思义就是读取一个字符,其用法如下:
- 头文件:#include<stdio.h>
- 声明:int getchar()
- 作用:从标准输入 stdin 获取一个字符(一个无符号字符)
- 返回值:该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF。
下面的实例演示了 getchar() 函数的用法:
#include <stdio.h>
int main()
{
char c;
printf("请输入字符:");
c = getchar();
printf("输入的字符:");
putchar(c);
return 0 ;
}
输出结果:

5. 多字符输入函数
多字符输入函数——gets,顾名思义就是输入一个字符,其用法如下:
- 头文件:#include<stdio.h>
- 声明:char *gets(char *str)
- str -- 这是指向一个字符数组的指针,该数组存储了 C 字符串。
- 作用:从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中。
- 返回值:如果成功,该函数返回 str。如果发生错误或者到达文件末尾时还未读取任何字符,则返回 NULL。
下面的实例演示了 gets() 函数的用法:
#include <stdio.h>
int main()
{
char str[20] = { 0 };
printf("请输入一个字符串:");
gets(str);
printf("您输入的字符串是:%s", str);
return(0);
}
输出结果:

6. 格式化输入函数
6.1 语法
下列是格式化输入函数——scanf的用法:
- 头文件:#include<stdio.h>
- 声明:int scanf(const char *format, ...)
- format -- 这是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符和 format 说明符。
- 作用: 从标准输入 stdin 读取格式化输入
- 返回值:如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
下面的实例演示了 scanf() 函数的用法:
#include<stdio.h>
int main()
{
int a, b, c;
printf("请输入三个数字:");
scanf("%d%d%d", &a, &b, &c);
printf("输出结果是:%d,%d,%d\n", a, b, c);
return 0;
}
- &a、&b、&c 中的 & 是地址运算符,分别获得这三个变量的内存地址。
- %d%d%d 是按十进值格式输入三个数值。输入时,在两个数据之间可以用一个或多个空格、tab 键、回车键分隔。
输出结果:

- 并且输入数据也要与格式化内数据保持一致。什么意思呢?我们以下面这段代码举例说明:
#include<stdio.h>
int main()
{
int a, b;
scanf("%d,d", &a, &b);
//输入a,b?
//输入a b?
printf("输出结果是:%d,%d\n", a, b, );
return 0;
}
- 上诉代码只能输入a,b,而不能输入a b因为要与格式化内容相匹配。
6.2 scanf与gets之间的区别
scanf在处理占位符时候,如果占位符不是%c,会忽略起始的空格(非起始的空格会停止),换行符,制表符。而gets可以将输入流的数据全部读取。比如说下面这段代码:
#include<stdio.h>
//如果输入hello betty
//分别输出什么
int main()
{
char arr1[20];//存放字符串
gets(arr1);
char arr2[20];//存放字符串
scanf("%s ", arr2);
printf("arr1输出:%s\n",arr1);
printf("arr2输出:%s\n", arr2);
return 0;
}

- 第一次输入gets全部读取,第二次输入printf遇见空格就停止读取。
6.3 缓存区
scanf() 处理用户输⼊的原理是,用户的输⼊先放⼊一个区域,等到按下回⻋键后,按照占位符对缓存进⾏解读。而这个区域就是我们的缓存区。

注:标准输入⼀般指的就是键盘,标准输出⼀般指的就是屏幕
知道了缓冲区之后,让我们来分析一段代码:
int main()
{
char password[20];
printf("请输入你的密码:");
scanf("%s", password);
int ret = getchar();
printf("请再次确认你的密码(Y/N):");
if (ret == 'Y')
{
printf("密码正确\n");
}
else
{
printf("密码错误\n");
}
return 0;
}
输出结果:

为什么会出现这样的结果呢?这时就要运用缓冲区的知识,在我们输入abc回车(\n)时,缓冲区中的数据为abc\n,而scanf只会读取abc,\n会被一直留在缓冲区。所以在getchar再次读取时会自动读取\n,输出密码错误。
解决这个问题也很简单,我们只需要再加一个getchar提前把\n读取就行了。
int main()
{
char password[20];
printf("请输入你的密码:");
scanf("%s", password);
printf("请再次确认你的密码(Y/N):");
getchar();//清空缓冲区
int ret = getchar();
if (ret == 'Y')
{
printf("密码正确\n");
}
else
{
printf("密码错误\n");
}
return 0;
}
6.4 scanf的返回值
如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。这一点常常用于多组数据输入,比如说多组数据求和,可以写成如下形式:
int main()
{
int a, b;
while (scanf("%d%d") == 2)
{
int sum = a + b;
printf("%d", sum);
}
return 0;
}
- 在VS环境下可以按3次 ctrl+z 强制结束。
玩转C语言:深入理解输入输出函数的奥秘的更多相关文章
- C 语言-----字符串和输入输出函数
在C语言中,没有字符串类型,那它是怎么表示字符串呢? 由于字符串是一系列单个字符的组合,所以它用char 类型的数组来表示字符串,在数组中,一个数组元素存放一个char类型字符. ]; name 变量 ...
- C语言的基本输入与输出函数(全解)
C语言的基本输入与输出函数 1.1.1 格式化输入输出函数 Turbo C2.0 标准库提供了两个控制台格式化输入. 输出函数printf() 和scanf(), 这两个函数可以在标准输入输出设备上以 ...
- C语言的基本输入与输出函数
C语言中最常用最基础的输入输出函数:printf() 和 scanf(); 例子: #import <Foundation/Foundation.h> int main(int argc, ...
- c语言的输入输出函数
参考文章: http://blog.sina.com.cn/s/blog_784f40b80100psg9.html C语言输入输出函数分为两类: 1.格式化输入输出函数 2.非格式化输入输出 --- ...
- C语言中最常用的三种输入输出函数scanf()、printf()、getchar()和putchar()
本文给大家介绍C语言中最常用的三种输入输出函数scanf().printf().getchar()和putchar(). 一.scanf()函数格式化输入函数scanf()的功能是从键盘上输入数据,该 ...
- c语言输入输出函数
上学年学习c语言的时候比较匆忙,没好好吸收. 现在有时间好好复习下. 本文就c语言常见输入函数进行简单介绍,对比. ps:由于自己能力有限,时间有限,多数介绍,总结都是摘录网上相关学习资料,下面给出本 ...
- C语言学习<输入输出函数,函数的调用>
#include <stdio.h> /* 输入输出函数的学习 函数的调用 2017.05.25 soulsjie */ //输入连个数字求最大值 void main(){ int Max ...
- C语言中输入输出函数
1.1.1 格式化输入输出函数Turbo C2.0 标准库提供了两个控制台格式化输入. 输出函数printf() 和scanf(), 这两个函数可以在标准输入输出设备上以各种不同的格式读写数据.pri ...
- C语言 · 字符串输入输出函数
算法提高 3-2字符串输入输出函数 时间限制:1.0s 内存限制:512.0MB 描述 编写函数GetReal和GetString,在main函数中分别调用这两个函数.在读入一个实数 ...
- C++中的字符串的输入输出函数、空字符与空格的区别、字符变量赋值和字符串初始化
一.字符串输入输出函数 1. cin.get() 逐个字符输入输出 2. cin 可以将整个字符串一次性输入,但是,cin将空格.Tab和回车键,因此不能用于数组的一次性输入. 注意:ci ...
随机推荐
- [转帖]Java程序在K8S容器部署CPU和Memory资源限制相关设置
2019-04-297279 版权 本文涉及的产品 容器服务 Serverless 版 ACK Serverless,317元额度 多规格 推荐场景: 立即试用 容器镜像服务 ACR,镜像仓库100个 ...
- [转帖]Linux 内核的 4 大 IO 调度算法
https://cloud.tencent.com/developer/article/1615744 Linux 内核包含4个IO调度器,分别是 Noop IO scheduler.Anticipa ...
- [转帖]Skip List--跳表(全网最详细的跳表文章没有之一)
https://www.jianshu.com/p/9d8296562806 跳表是一种神奇的数据结构,因为几乎所有版本的大学本科教材上都没有跳表这种数据结构,而且神书<算法导论>.< ...
- [转帖]Kafka需要知道的一些基础知识点
https://blog.csdn.net/daima_caigou/article/details/109101405 前言 kafka是常用MQ的一种,站在使用者的角度来看待,kafka以及所有的 ...
- React Hooks 指北
前言 这篇文章旨在总结 React Hooks 的使用技巧以及在使用过程中需要注意的问题,其中会附加一些问题产生的原因以及解决方式.但是请注意,文章中所给出的解决方式并不一定完全适用,解决问题的方案有 ...
- vue写组件时的命名规范
1组件命名驼峰 如myBread.vue(组件) 2引入时,接受同样是驼峰 import MyBread from "@/components/cuscom/myBread.vue" ...
- 基于spring security创建基本项目框架
SpringBoot建项目步骤 建表 新建项目 (package name可以自定义,整个项目只能在该包下) 选择可能有到的依赖 (别忘了勾选SQL中的Mybatis Framework,创建项目 如 ...
- docker容器中部署 kafka 和 elk
1.下载zookeeper docker pull wurstmeister/zookeeper 2.下载kafka docker pull wurstmeister/kafka:2.11-0.11. ...
- Windows 堆管理机制 [2] Windows 2000 – Windows XP SP1版本
2.Windows 2000 – Windows XP SP1 2.1 环境准备 环境 环境准备 虚拟机 32位Windows 2000 SP4 调试器 OllyDbg.WinDbg 编译器 VC6. ...
- Git如何拉取指定远程分支
转载来自https://www.jianshu.com/p/856ce249ed78 目的 我们想要获取到代码仓库中分支"a" 中的文件到本地,我了解到有三种方法. 代码仓库 ...
