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