scanf这个函数--论坛里的一个帖子
2011-04-25 23:13
399 查看
原帖地址:http://topic.csdn.net/u/20110423/19/a1e4c5ae-5b44-4e94-8f2c-55f7ba6486de.html
int a;
char b;
printf("请输入a的值");
scanf("%d",&a);
getchar()//假如这里不加getchar,那么后面的输入都直接无效了
printf("请输入b的值:");
scanf("%c",&b);
大家看看这个程序,假如把输入字符放在输入整数之前,那么不用加getchar(),否则必须加getchar(),这到底是怎么回事??
处理空白符的问题,当 scanf 中的输入格式说明符 (Format specifiers) 是 "%c"的时候,那么空白字符 (whitespace) 将会被正常读入,不再起到分隔符的作用。这个时候要注意处理缓冲区中残留的空白符
那为什么将scanf("%c",&b)与scanf("%d",&a)交换过来就不会出现这样的情况,不是也有个换行符在缓冲区中吗??
引用 3 楼 mmothermother 的回复:
那为什么将scanf("%c",&b)与scanf("%d",&a)交换过来就不会出现这样的情况,不是也有个换行符在缓冲区中吗??
当 scanf 中的输入格式说明符 (Format specifiers) 不是 "%c"的时候,那么空白字符 (whitespace) 将起到分隔符的作用。把分隔好的两个数据分别赋值到各自定义好的变量或数组中去,两个数据之间的 whitespace 被从缓冲区读出但是不起任何作用,当然最后一个 '/n' 会被留在缓冲区内,除非用 getchar(); 或 scanf("%c",&ch); 把它读出来。
引用 8 楼 mmothermother 的回复:
引用 6 楼 delphiwcdj 的回复:
引用 3 楼 mmothermother 的回复:
那为什么将scanf("%c",&b)与scanf("%d",&a)交换过来就不会出现这样的情况,不是也有个换行符在缓冲区中吗??
当 scanf 中的输入格式说明符 (Format specifiers) 不是 "%c"的时候,那么空白……
仔细看下6L的解释 注意什么时候把空白字符当成分隔符什么时候不当
想象输入设备(键盘)连接着一个叫“缓冲”的东西,把缓冲认为是一个字符数组。当你的程序执行到scanf时,会从你的缓冲区读东西,如果缓冲区是空的,就阻塞住,等待你从键盘输入。 现在假设你的缓冲区里有: abcd/n1234/n (其中/n是回车符) 执行: scanf("%s",name); 的时候,由于scanf是读数据直到看见空白符(空白符:指空格符、制表符、回车符)就停止的输入函数。所以执行后,把abcd存到了name中。缓冲区于是变成了 /n1234/n 接下来的执行就有问题了,如果遇到了: scanf("%d",&number); 怎么办?因为遇到了回车符,它并不是一个数字,所以应该抛出错误,让程序死掉?不对吧,明明是编程序的你让用户输入完名字回车的(不然怎么提示用户该输入数字了?),怎么能出尔反尔地报错呢? 所以scanf还有一个特性,就是忽略先导的空白符。不管是有几百个回车也好,几万个空格也罢,只要它们连续地出现在缓冲区的开头,就统统忽略他们。然后再读有意义的字符。于是1234被读入number。 回到刚刚,当缓冲区还是: /n1234/n 的时候,如果遇到了: scanf("%c",&sex); 应该怎么办呢?你说,那好办呀,不是说了忽略前导空白符吗?跳过回车读'1'呀! 想法是好的,可这只针对你的程序这一种情况。如果我编写的程序就是统计用户输入了多少个回车呢?缓冲里明明有回车符,却读不出来,你不是忽悠我吗? 所以对scanf来讲跳过前导空白符有个例外,当参数是%c的时候,就把缓冲区的第一个字符返回回去,不管是什么。 这样的设计就有个问题,scanf对不同的参数表现出来的特性不一样。 得承认,这是个缺陷,但不是说这样不好。 这样的设计至少把发现所有字符的机会交给了用户, 设计者这样想: 如果程序员使用了scanf("%c",..),那他就有必要知道这函数能把回车符读出来,至于程序员对回车符感不感兴趣,那就看他了,不感兴趣的话,程序员也一定知道该怎么处理。 回到你的程序里。 当执行scanf("%s",name)的时候,要求你从键盘输入, 于是你输入了"abc",然后“回车”。 缓冲区里自然而然地是: abc/n scanf把abc拿走了,留下了/n,缓冲区里现在就剩下/n 于是,下一个scanf ("%c",&sex); 想当然地读取了/n 明白了? 关于scanf忽略前导空白符这一点,可以这样验证: 写个程序,用scanf()读数据,只要不是%c就行。 然后输入的时候,随便输入回车、空格、制表符,然后“回车”确认。 会发现程序依然提示等待你输入。 就是因为它忽略掉所有前导空白符之后发现缓冲区是空的!于是乖乖地阻塞住,等待你输入。关于scanf是直到看见空白符结束读取这一点,如果你是初学C的话,那么很快你就会遇到另一个函数,叫gets()。 程序里如果我们想一次读入一个英文句子: I am a student. 如果你用scanf读的话,只能读出"I",想读出后面的东西要不断调scanf。 此时需要用gets,这个函数不管是什么一律读进来,直到遇到回车符才停下。 总之,各有各的用途,全都熟悉之后,才能在恰当的时候恰当地使用。
本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/wangyadong/archive/2009/04/23/4103774.aspx
的却,如果人人都用万能钥匙,那天下就没有钥匙了
int a;
char b;
printf("请输入a的值");
scanf("%d",&a);
getchar()//假如这里不加getchar,那么后面的输入都直接无效了
printf("请输入b的值:");
scanf("%c",&b);
大家看看这个程序,假如把输入字符放在输入整数之前,那么不用加getchar(),否则必须加getchar(),这到底是怎么回事??
处理空白符的问题,当 scanf 中的输入格式说明符 (Format specifiers) 是 "%c"的时候,那么空白字符 (whitespace) 将会被正常读入,不再起到分隔符的作用。这个时候要注意处理缓冲区中残留的空白符
那为什么将scanf("%c",&b)与scanf("%d",&a)交换过来就不会出现这样的情况,不是也有个换行符在缓冲区中吗??
引用 3 楼 mmothermother 的回复:
那为什么将scanf("%c",&b)与scanf("%d",&a)交换过来就不会出现这样的情况,不是也有个换行符在缓冲区中吗??
当 scanf 中的输入格式说明符 (Format specifiers) 不是 "%c"的时候,那么空白字符 (whitespace) 将起到分隔符的作用。把分隔好的两个数据分别赋值到各自定义好的变量或数组中去,两个数据之间的 whitespace 被从缓冲区读出但是不起任何作用,当然最后一个 '/n' 会被留在缓冲区内,除非用 getchar(); 或 scanf("%c",&ch); 把它读出来。
引用 8 楼 mmothermother 的回复:
引用 6 楼 delphiwcdj 的回复:
引用 3 楼 mmothermother 的回复:
那为什么将scanf("%c",&b)与scanf("%d",&a)交换过来就不会出现这样的情况,不是也有个换行符在缓冲区中吗??
当 scanf 中的输入格式说明符 (Format specifiers) 不是 "%c"的时候,那么空白……
仔细看下6L的解释 注意什么时候把空白字符当成分隔符什么时候不当
想象输入设备(键盘)连接着一个叫“缓冲”的东西,把缓冲认为是一个字符数组。当你的程序执行到scanf时,会从你的缓冲区读东西,如果缓冲区是空的,就阻塞住,等待你从键盘输入。 现在假设你的缓冲区里有: abcd/n1234/n (其中/n是回车符) 执行: scanf("%s",name); 的时候,由于scanf是读数据直到看见空白符(空白符:指空格符、制表符、回车符)就停止的输入函数。所以执行后,把abcd存到了name中。缓冲区于是变成了 /n1234/n 接下来的执行就有问题了,如果遇到了: scanf("%d",&number); 怎么办?因为遇到了回车符,它并不是一个数字,所以应该抛出错误,让程序死掉?不对吧,明明是编程序的你让用户输入完名字回车的(不然怎么提示用户该输入数字了?),怎么能出尔反尔地报错呢? 所以scanf还有一个特性,就是忽略先导的空白符。不管是有几百个回车也好,几万个空格也罢,只要它们连续地出现在缓冲区的开头,就统统忽略他们。然后再读有意义的字符。于是1234被读入number。 回到刚刚,当缓冲区还是: /n1234/n 的时候,如果遇到了: scanf("%c",&sex); 应该怎么办呢?你说,那好办呀,不是说了忽略前导空白符吗?跳过回车读'1'呀! 想法是好的,可这只针对你的程序这一种情况。如果我编写的程序就是统计用户输入了多少个回车呢?缓冲里明明有回车符,却读不出来,你不是忽悠我吗? 所以对scanf来讲跳过前导空白符有个例外,当参数是%c的时候,就把缓冲区的第一个字符返回回去,不管是什么。 这样的设计就有个问题,scanf对不同的参数表现出来的特性不一样。 得承认,这是个缺陷,但不是说这样不好。 这样的设计至少把发现所有字符的机会交给了用户, 设计者这样想: 如果程序员使用了scanf("%c",..),那他就有必要知道这函数能把回车符读出来,至于程序员对回车符感不感兴趣,那就看他了,不感兴趣的话,程序员也一定知道该怎么处理。 回到你的程序里。 当执行scanf("%s",name)的时候,要求你从键盘输入, 于是你输入了"abc",然后“回车”。 缓冲区里自然而然地是: abc/n scanf把abc拿走了,留下了/n,缓冲区里现在就剩下/n 于是,下一个scanf ("%c",&sex); 想当然地读取了/n 明白了? 关于scanf忽略前导空白符这一点,可以这样验证: 写个程序,用scanf()读数据,只要不是%c就行。 然后输入的时候,随便输入回车、空格、制表符,然后“回车”确认。 会发现程序依然提示等待你输入。 就是因为它忽略掉所有前导空白符之后发现缓冲区是空的!于是乖乖地阻塞住,等待你输入。关于scanf是直到看见空白符结束读取这一点,如果你是初学C的话,那么很快你就会遇到另一个函数,叫gets()。 程序里如果我们想一次读入一个英文句子: I am a student. 如果你用scanf读的话,只能读出"I",想读出后面的东西要不断调scanf。 此时需要用gets,这个函数不管是什么一律读进来,直到遇到回车符才停下。 总之,各有各的用途,全都熟悉之后,才能在恰当的时候恰当地使用。
本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/wangyadong/archive/2009/04/23/4103774.aspx
的却,如果人人都用万能钥匙,那天下就没有钥匙了
相关文章推荐
- 看论坛一个帖子带来的震撼--熟悉函数多么重要(glob函数)
- 用c语言实现 编写一个函数,将一个数字字符串转换成这个字符串对应的数字(包括正浮点数、负浮点数)
- 转载QT中文论坛的一个帖子,版本比较老了,但是说的比较全,有了框架再干活比较顺。
- 引用一个论坛的帖子学习 group ib order max组合查询
- 一个登录论坛并上传帖子和文件的代码
- 编写一个函数,返回一个int数组中存储的最大数值,并在一个简单的程序中测试这个函数。(有缺陷)
- 【c语言】为下面的函数原型编写函数定义,这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。
- 【c语言】编写一个函数,将一个数字字符串转换成这个字符串对应的数字(包括正浮点数、负浮点数)
- 这个字符串参数必须包含一个或多个数字,函数应该把这些 数字字符转换为整数并返回这个整数。如果字符串参数包含 了任何非数字字符,函数就返回零。
- 我发现了一个贼屌的大神的博客。这个帖子只为存储他的博客地址
- 编写一个函数,从标准输入读取一列整数, 把这些值存储在一个动态分配的数组中并返回这个数组。 函数通过观察EOF判断输入列表是否结束。 数组的第一个数是数组包含的值的个数, 它的后面就是这些整数值。
- 转载QT中文论坛的一个帖子,版本比较老了,但是说的比较全,有了框架再干活比较顺。
- 当读入一个数字,scanf()函数的写法
- 享变量内有一个函数指针,是外部传进来的。 可我一使用这个函数指针,就出错了
- 实现一个函数stringToInt,实现把字符串转换成整数这个功能
- 一个字符变量存储到动态分配内存引发的输入问题解决--连续输入scanf函数存在缓冲区的问题
- 写一个函数,输入一串字符串,求这个字符串中有多少个英文,多少空格,多少个数字,多少个其它字符
- 【C语言】为下面的函数原型编写函数定义: int ascii_to_integer(char *str); 这个字符串参数必须包含一个或者多个数字,函数应该把这些数字字符转换为整数并返回这个整数。
- C语言 编写一个函数,将一个数字字符串转换成这个字符串对应的数字(包括正浮点数、负浮点数)
- 在终端输出字符串,然后封装一个函数,这个函数的功能是:去掉输入的字符串中的空格