scanf大概率只是在C语言上机作业或者算法比赛或考试中广泛使用的一个函数,在实际项目中直接使用的概率应该很低,但是做一些算法模拟的时候却很有用处,值得花点时间稍微掌握一下。
- scanf的输入格式
- 从一个简单的示例开始
- scanf() vs gets()
- getchar() vs getche() vs getch()
- 常见问题:无法获取的%c
注:诸如%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]