【C语言】scanf 函数的使用
C语言通过 scanf 函数读取键盘输入,键盘输入又被称为标准输入(stdin)。
当 scanf 函数读取标准输入时,如果没有任何内容,那么 scanf 函数会被阻塞。
scanf 函数的声明:
#include <stdio.h>
int scanf(const char *format, ...);
scanf 函数根据给出的 format 格式将值读取到匹配的变量空间中。
返回的值的匹配成功的成员个数,中间有任何一个成员匹配出错,后面的成员都会匹配出错。
scanf 函数的原理
当我们使用 scanf 函数时,从键盘输入的一切数据,不管是数字、字母,还是空格、回车、Tab 等字符,都会被当作数据存入缓冲区。存储的顺序是先输入的排前面,后输入的依次往后排。按回车键的时候 scanf 开始进入缓冲区取数据,从前往后依次取。
#include <stdio.h>
//scanf 用来读取标准输入,scanf 是把标准输入内的内容放到某个变量空间里。因此变量必须取地址
//scanf 会阻塞,是因为标准输入缓冲区是空的
int main() {
int i, ret;
char c;
float f;
scanf("%d", &i); //&是取地址符
printf("i=%d\n", i); //把标准缓冲区中的整型数据读走
// fflush(stdin); //清空标准缓冲区
scanf("%c", &c);
printf("c=%c\n", c);
scanf("%f", &f);
printf("f=%f\n", f);
return 0;
}
运行结果:
当我们输入 123 并按下回车时(按下回车时 scanf 函数才开始匹配),此时 stdin 中的内容是 "123\n",scanf 函数中的 %d 匹配整型数20,放入变量 i 中。
scanf 函数匹配一个字符时,会在 stdin 删除对应的字符。这时 '\n' 仍然在 stdin 内,如果第二个 scanf 函数为 scanf("%d, &i);
,那么依然会发生阻塞,因为 scanf 函数在读取整型数、浮点数、字符串时,会忽略 '\n'、空格符等字符(忽略是指 scanf 函数执行时会首先删除这些字符,然后再阻塞)。
但scanf 函数在读取字符时,不会忽略任何字符,所以 scanf("%c", &c);
读取了 stdin 中残留的 '\n',不发生阻塞。
在读取字符型数据前,通过 fflush(stdin);
清空缓冲区即可解决此问题。
【注意】在 scanf 函数中,所有的“非输入控制符”都要原样输入。所以对于scanf("i=%d", &i);
,在输入时必须输入 i=123
才正确。所以在 scanf 尽量不要加任何“非输入控制符”。
多种数据类型混合输入
从键盘输入数据同时给多个变量赋值时,值之间一定要用空格、回车或者 Tab 键隔开,用以区分是给不同变量赋的值。而且空格、回车或 Tab 键的数量不限,一般都使用一个空格。
当我们让 scanf 函数一次读取多种类型的数据时,必须要格外小心字符型数据。
#include <stdio.h>
int main() {
int i, ret;
char c;
float f;
ret = scanf("%d%c%f", &i, &c, &f);
printf("i=%d, c=%c, f=%5.2f, ret=%d\n", i, c, f, ret);
fflush(stdin);
ret = scanf("%d %c%f", &i, &c, &f); //在%c之前加上空格解决字符型数据读取问题
printf("i=%d, c=%c, f=%5.2f, ret=%d\n", i, c, f, ret);
return 0;
}
运行结果:
循环读取多个整型元素
#include <stdio.h>
int main() {
int a[5];
for (int i = 0; i < 5; ++i) { //循环读取多个整型元素
scanf("%d",&a[i]);
}
for (int i = 0; i < 5; ++i) {
printf("%-3d",a[i]);
}
printf("%c",'\n');
return 0;
}
本文来自博客园,作者:hzyuan,转载请注明原文链接:https://www.cnblogs.com/hzyuan/p/17948353
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
2022-01-06 【算法】计数排序
2022-01-06 【java】比较器的使用