scanf的陷阱
来源:互联网 发布:淘宝上的epiphone 编辑:程序博客网 时间:2024/05/21 09:38
scanf函数从标准输入流得到数据。以下几点需要注意:
1、scanf的返回值表示成功读入数据的个数。何为成功读入?例如,scanf("%d%d", &a, &b); 要求读入2个十进制的整数,scanf会到输入缓冲区中寻找。如果成功找到2个整数就返回2;如果找到1个就返回1,表示只有a被成功读入;如果找完整个输入缓冲区都没有找到,就返回0,表示读入失败。
程序如下:
#include<stdio.h>
int main()
{
int a=1,b=1;
int ret;
ret = scanf("%d %d",&a,&b);
printf("a=%d b=%d\n",a,b);
printf("ret=%d\n", ret);
return 0;
}
输入2个整数:
2 3 //输入
a=2 b=3 //输出
ret=2 //输出
输入2个字符:
a b //输入
a=1 b=1 //输出
ret=0 //输出
当然,由于没有读取出a b,在缓冲区中的a b并不会消失。
2、scanf遇到空格、回车和Tab键都会认为输入结束。
程序如下:
#include<stdio.h>
int main()
{
char ch1[10];
#if 1
scanf("%s",ch1);
printf("%s\n", ch1);
#else
gets(ch1);
printf("%s\n", ch1);
#endif
return 0;
}
输入abc de
abc de //输入
abc //输出
将#if 1改为#if 0
输入abc de
abc de //输入
abc de //输出
关于scanf和gets的区别:
scanf :当遇到回车,空格和tab键会自动在字符串后面添加'\0',但是回车,空格和tab键仍会留在输入的缓冲区中。
gets:可接受回车键之前输入的所有字符,并用'\0'替代 '\n'.回车键不会留在输入缓冲区中。
如果非要用scanf,可以将scanf("%s",ch1);改为scanf("%[^\n]",ch1);表示接受除了'\n'外的任何字符。但是,'\n'仍然留在缓冲区中。
3、在用"%c"输入时,空格和“转义字符”均作为有效字符。
例如:
#include<stdio.h>
int main()
{
char ch1[10];
char c;
scanf("%s",ch1);
scanf("%c", &c);
printf("%s\n", ch1);
printf("%d\n", c);
return 0;
}
输入abc
abc //输入
abc //输出
10 //输出
10即'\n'的ASCII值
4、刷新缓冲区
在使用scanf时,如果不及时刷新输入缓冲区,有时会出现莫名其妙的错误。
例如:
#include<stdio.h>
int main()
{
int c;
do
{
scanf("%d",&c);
printf("%d\n", c);
}while (c != 20);
return 0;
}
程序意思是让用户输入一个整数,如果这个数不是20,就继续输入。
当用户输入整数时,这个程序能正常工作。但是,当输入的不是数字时,程序就会死锁,不断循环输出数字。
如何解决这个问题?这就需要用到scanf的返回值。当返回值不是1时,刷新缓冲区。
在windows中,可以使用fflush(stdin);来刷新输入缓冲区。但是,标准C并没有定义fflush对输入缓冲区的操作:
int fflush(FILE* stream);
Flushes stream stream and returns zero on success or EOF on error.
Effect undefined for input stream. fflush(NULL) flushes all output streams.
使用fflush是个很不明智的决定(gcc不支持fflush刷新输入缓冲区)。可以自己定义一个刷新输入缓冲区的函数:
void flush()
{
char c;
while ((c=getchar()) != '\n'&&c!=EOF) ;
}
这样就可以解决我们之前的问题了:
int main()
{
int c;
do
{
if (scanf("%d",&c) != 1)
flush();
else
printf("%d\n", c);
}while (c != 20);
return 0;
}
- scanf的陷阱
- scanf可能遇到的陷阱
- scanf的输入字符时的陷阱
- scanf使用的一个小陷阱
- 调用scanf函数的一个陷阱
- scanf 函数的 用法 以及陷阱
- scanf () 小陷阱。
- scanf 用法及陷阱
- scanf()中的陷阱
- gcc中使用scanf的一个小陷阱
- C陷阱与缺陷中有关scanf的一道题
- 谈C中scanf陷阱
- scanf用法及其中的陷阱
- 为什么scanf不起作用了--scanf用法及陷阱
- 谈C中scanf陷阱(转)
- scanf 用法及陷阱(转)
- scanf 用法及陷阱(转)
- scanf 用法及陷阱(转)
- 海量数据处理:十道面试题与十个海量数据处理方法总结
- 函数调用下形参和实参的内存分配
- android 布局随笔
- 低功耗设计中电容对系统的影响(二)
- java八种排序
- scanf的陷阱
- static数据成员 c++
- 有关针式打印机和一体机的安装
- 概率算法 -- 洗牌
- oracle游标的使用
- 关于Cookie的使用---web Cookie和js Cookie
- hibernate criteria的例子
- ORACLE TT--【每日一译】--2013-01-25
- VS2010中水晶报表应用与部署