C语言基础:scanf使用基础

scanf大概率只是在C语言上机作业或者算法比赛或考试中广泛使用的一个函数,在实际项目中直接使用的概率应该很低,但是做一些算法模拟的时候却很有用处,值得花点时间稍微掌握一下。

目录

  • scanf的输入格式
  • 从一个简单的示例开始
  • scanf() vs gets()
  • getchar() vs getche() vs getch()
  • 常见问题:无法获取的%c


scanf的输入格式

格式控制符说明
%c读取单个字符
%s读取一个字符串(以空格或者回车等为结束条件,注意遇空格即结束)
%d读取十进制整数,赋给int类型变量
%hd读取十进制整数,赋给short类型变量
%ld读取十进制整数,赋给long类型变量
%o读取八进制整数,赋给int类型变量
%ho读取八进制整数,赋给short类型变量
%lo读取八进制整数,赋给long类型变量
%x读取十六进制整数,赋给int类型变量
%hx读取十六进制整数,赋给short类型变量
%lx读取十六进制整数,赋给long类型变量
%u读取十进制整数,赋给unsigned int类型变量
%hu读取十进制整数,赋给unsigned short类型变量
%lx读取十进制整数,赋给unsigned long类型变量
%f读取十进制浮点数,赋给float类型变量
%lf读取十进制浮点数,赋给double类型变量
%e读取指数形势的浮点数,赋给float类型变量
%le读取指数形势的浮点数,赋给double类型变量
%g读取十进制或者指数形势的浮点数,赋给float类型变量
%lg读取十进制或者指数形势的浮点数,赋给double类型变量

注:诸如%a之类的C99等支持的格式并未展开


从一个简单的示例开始

示例代码如下

#include 
#include int main() {char str[20];while(scanf("%s",str) != EOF) {printf("[%d][%s]\n",strlen(str),str);}return 0;
}

一次性的输入多行内容,发现printf打印最后一行需要再次回车才能出现

/Users/liumiao/CLionProjects/untitled/cmake-build-debug/untitled
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#[8][.....#.#]
[8][##.....#]
[8][##.....#]
[8][.......#]
[8][#......#][8][#..#...#]

虽然和缓冲区有关,实际上还是最后一行的结束标志,比如回车符号没有拷贝,输入的时候在最后一行也保证换行被拷贝进去就可以了,比如

/Users/liumiao/CLionProjects/untitled/cmake-build-debug/untitled
.....#.#
##.....#
##.....#
.......#
#......#
#..#...#
[8][.....#.#]
[8][##.....#]
[8][##.....#]
[8][.......#]
[8][#......#]
[8][#..#...#]

当然也可以这样使用, 使用空格来分割不同输入:

/Users/liumiao/CLionProjects/untitled/cmake-build-debug/untitled
.....#.# ##.....# ##.....# .......# #......# #..#...#
[8][.....#.#]
[8][##.....#]
[8][##.....#]
[8][.......#]
[8][#......#]
[8][#..#...#]

另外,需要注意的是此处示例的str[20]并未初始化,也未指定字符串结束符,因为使用%s输入的时候,字符串结束标记’\0’会被拷贝进去。另外从这个例子中也可以看到scanf可以接受多行输入,结合printf逐行显示,说明是有一处空间保存相应内容的这实际就是scanf对于缓冲区的支持。


scanf() vs gets()

比较内容scanf()gets()
格式化输入支持不支持,没有形如"%s"的方式指定格式化输入
缓冲区存在缓冲区,按下回车,从缓冲区中读取内容与scanf相同
分隔符缺省以空格为分隔符,遇空格认为输入结束空格为输入的一部分,遇回车才会结束,gets能读取包含空格的字符串,scanf不能
后续支持后续的C标准支持新的C标准中gets已被剔除,使用gets_s替代

getchar() vs getche() vs getch()

获取单个字符getchar()的作用完全等同于scanf的%c,除了getchar之外,还有getche和getch两个常用函数,在这里顺便一起总结一下。

函数 缓冲区头文件回显适用平台
getchar()stdio.h
getche()conio.h
getch()conio.h

常见问题:无法获取的%c

如下代码示例:

#include int main() {int num=0, c=0;scanf("%d",&num);scanf("%c",&c);printf("[num=%d][c=%c]\n",num,c);return 0;
}

输入1001然后直接回车,结果如下

1001
[num=1001][c=
]

因为这里可以显示地看到变量c获取并输出的回车,所以严格来说这并不是一个问题,比如如下方式输入就可以获得正确输出

1001m
[num=1001][c=m]

但是这种方式在两个输入之间无法加入空格,因为否则空格会被scanf认为是要读入的内容。可以简单的使用getchar来实现去除回车的影响。

#include int main() {int num=0, c=0;scanf("%d",&num);getchar();scanf("%c",&c);printf("[num=%d][c=%c]\n",num,c);return 0;
}

需要注意的是getchar获取的是单个字符,所以这样1001 m的输入就可以正常显示了

1001   m
[num=1001][c=m]

或者两行输入的方式

1001
m
[num=1001][c=m]

但是如果1001和m之间多于一个空格,变量c会赋成空格,实际上可以更简单,比如改成这样

#include int main() {int num=0, c=0;scanf("%d %c",&num,&c);printf("[num=%d][c=%c]\n",num,c);return 0;
}

这样1001 m的输入也可以正常显示了

1001   m
[num=1001][c=m]

或者两行输入的方式

1001
m
[num=1001][c=m]


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部