| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1446 人关注过本帖
标题:经验分享!!关于scanf()函数
只看楼主 加入收藏
sophia
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2004-9-5
收藏
 问题点数:0 回复次数:8 
经验分享!!关于scanf()函数

对于学C的人而言,scanf()你应该不会陌生,它至少是你最常用的几个scanf()之一.但是,你是否就认为很容易呢,对于初学者而言,你可能经常在这上面犯些你自已无法发现的小错误,请先看看下面的这个程序,如果你能解决这个问题的话,那么这篇文章对你可能就没有多大的价值了,应该说,这是一篇与初学者分享的文章. (为了讨论的方便,下面这段程序输入数据时按递增的方式进行,毕竟,这不是本文的重点)

#include "stdio.h"

main() { int a,i,first,end,mid; int flag=0; int data[10]; printf("Please input 10 numbers:\n"); for(i=0;i<=9;i++) scanf("%d",&data[i]); printf("\n"); scanf("Please input a number you want to find in 10 numbers:%d",&a); printf("\n"); first=0; end=9; mid=(first+end)/2; while(first<=end) { mid=(first+end)/2; if(data[mid]>a) end=mid-1; else if(data[mid]<a) first=mid+1; else { flag=1; break; } } if(flag) printf("The number you find is%d\n",data[mid]); else printf("don't find the number!\n"); getch(); }

首先,我们来看scanf()的格式: scanf(格式控制,地址列表); 作为最简单的情况是格式控制中只包含格式说明而没有其他字符,例如"%d%d".对于这种形式,我想你知道如何去处理.在输入的时候两个数据之间以一个或多个空格间隔,也可用回车,tab跳格键.需要提醒的是:这只是对于输入整数(即int)形式.如果是像 scanf("%c%c",&a,&b); 这样的话,你应该不会用空格什么的去间隔字符,事实上这是不必要的,它只会给带来麻烦,相反地,我们甚至必须考虑怎样去消除意外的错误.简单地说,你必须记住现在的空格,回车都成了一个字符,你可以通过下面这段程序来验证一下:

#include <stdio.h> main() { int a,b; char c,d; scanf("%d%d",&a,&b); printf("%d %d\n",a,b); scanf("%c%c",&c,&d); printf("%c %c\n",c,d); } 如果你输入的是 1(空格)3(回车) a(空格)b(回车) 那么,程序运行的结果会是什么呢?你可以自已运行试试.结果是 1(空格)3(回车) 1 3 a(空格)b(回车) (空行) a (!!!!表达可能不太准确,你自已运行这段程序可能会帮助你弄明白我在说些什么!!!)

为什么会是这样的呢.那是因为,在第一次输入数据的回车换行符和变量b的类型不一样,不能赋给变量b,至使其保留在键盘缓冲区,这样,当第二个scanf()执行时,便把回车换行符作为第一个字符读取到了c中,如果你在TC中用调试器观察一下c的值,会发现此时c='\n',而不是你想要的得到的c='a'!! 如何解决这个问题,你可以修改程序,在第二个scanf()之前加上一个 getchar(); 它会帮你吸收掉键盘缓冲区间的'\n',如果你不想改变源程序的话,你的输入必须像下面这样 1(空格)3ab 一次将数据全部输入到键盘缓冲区,接下来读取数据的过程就交给scanf()函数了,当然,这样的过程 是比较难以理解的,所以,我的建议是尽量不要scanf()来输入字符,而是利用另外一个函数getch(); 相对于 scanf("%c%c",&a,&b); 而言 a=getch();b=getch(); 这样的语句更能让你知道明白自已在干些什么!

OK.接下来的问题似乎变得有点容易了,如果你理解了上面的内容的话.我们来看看在格式控制中还有其他字符的情况: scanf("%d,%d",&a,&b); scanf("This is %d",&a); 单独地考虑上面的两条语句,你肯定知道如何去处理,那么我们复杂一点,将这两条语句放到一起.请看下面的程序:

main() { int a,b,c; scanf("%d%d",&a,&b); scanf("This is %d",&c); printf("a=%d,b=%d,c=%d",a,b,c); getch(); } 对照上一个程序,我想你可能已经知道如何处理了,可以在你的TC上验证一下你的想法,正确的输入方式是: 15(空格或回车)25This is 35 这样的话,程序运行的如果将是: a=15,b=25,c=35 不要企图用其他的方式得到上面这个输出结果,除非你的输入方式跟上面的一样!既然这样,那就让我们来讨论一下诸如 scanf("This is %d",&c); 这样的输入方式,在输入时,格式控制中的字符是必须严格地配对的,你必须保证在你输入This is 35时This前没有空格,回车等其他的字符,严格地说,你必须保证在执行这条语句时键盘缓冲区没有字符.这也是为什么上例中25和This这间不能有空格(否则地话,第二个scanf()将无法成功地为c赋值,c的值将是在定义的时候随机产生的一个值,这个值直接地决定于所分配的内存中原来保存的数值),你可以通过尝试其他的输入方式来看看会出现什么样的结果!!

好了,到此为止,我想你应该已经明白了我在说些什么了,可能你会想,这是多么简单的东西啊,如果这样的话,那么我要祝贺你了,写这篇文章,只是为了能给初学者起个抛转引玉的作用,作为经验与大家分享.不对的地方请高手指点...........

最后,就让我们再来看看开始的程序吧,你一定已经知道答案了!问题就出来第二个scanf()上,准确地说,这段代码并没有错,但是却会让你不经意地犯下错误.如果将 scanf("Please input a number you want to find in 10 numbers:%d",&a); 分成两个语句: printf("Please input a number you want to find in 10 numbers:"); scanf("%d",&a); 就能更好地理解了.否则,你的输入应该像下面这样: 1 2 3 4 5 6 7 8 9 10Please input a number you want to find in 10 number:2

[此贴子已经被作者于2004-09-09 13:06:43编辑过]

搜索更多相关主题的帖子: scanf 函数 经验 分享 
2004-09-09 11:14
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

首先:scanf()是多参数函数,但是在使用的时候你要注意(使用scanf()会出现很多意想不到的问题)。

有人说过在大型程序设计中永远不要使用scanf()函数。

其次:我记得scanf()函数与fscanf( int stdin,.......)是一样的。

2004-09-09 11:24
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 
楼主此文是转贴还是自己的心得?

九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2004-09-09 11:28
mikewolf
Rank: 1
等 级:新手上路
帖 子:175
专家分:0
注 册:2004-7-3
收藏
得分:0 

我个人认为可以通过访问键盘缓冲区来改写库函数scanf()。

不知道高手有没有更好的方法!

2004-09-09 11:28
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 
有一个fflush函数
 fflush(stdin);

九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2004-09-09 11:31
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 

楼主,你再试试我改过的程序。

main() { int a,b,c; scanf(" %d %d",&a,&b); /* scanf("This is %d",&c); 首先你这是个错误用法,建议你重新学习一下scanf()*/ scanf(" %d",&c); printf("a=%d,b=%d,c=%d",a,b,c); getch(); }


九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2004-09-09 11:35
sophia
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2004-9-5
收藏
得分:0 

说明下,这是我自已的经验心得。还有,这篇文章只是讨论的是面对一个现有的程序,如何来输入以保证正确性,至于如何设计一个好的能够处理各种错误和正确的输入的程序那可能真的是scanf()不能解决的了(至少有点困难)

另外,请教下knocker大哥,上面的输入方式为什么是错误的。至少我认为是正确的,而且运行也正确。请指点!!

2004-09-09 13:05
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 
以下是引用sophia在2004-09-09 13:05:16的发言:

说明下,这是我自已的经验心得。还有,这篇文章只是讨论的是面对一个现有的程序,如何来输入以保证正确性,至于如何设计一个好的能够处理各种错误和正确的输入的程序那可能真的是scanf()不能解决的了(至少有点困难)

另外,请教下knocker大哥,上面的输入方式为什么是错误的。至少我认为是正确的,而且运行也正确。请指点!!

1.首先,你发了这篇文章说明你对scnaf()进行了一些探索,现在很有很多C的教科书对scanf()

printf()的解释并不完全,我估计作者的本意义是认为学习者以后开发软件不会使用C,会进而学

习C++,那么,在C++中很少会使用以上两个函数了,因为cin,cout更方便.

2. scanf(" This is %d",&c);你的意图是什么?你认为scanf会打印 " This is"吗?不会,This is在

这里只起了个控制符的作用。

即这句真正的意思是:让你输入"This is"后再输入变量C

也就是说This is是要你输入的,而scanf将忽略“This is”。

这样,再回到

scanf(" %d %d",&a,&b);我加了两个空格在%前,空格也是scnaf的控制符,它的意思就是过滤空格,回车,TAB,Newline等等空白符,也就解决你的问题。

3。getch()能解决问题,但是不是最佳的,请查看fflush函数用法及功能。


九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2004-09-09 13:59
sophia
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2004-9-5
收藏
得分:0 
以下是引用knocker在2004-09-09 13:59:09的发言:

2. scanf(" This is %d",&c);你的意图是什么?你认为scanf会打印 " This is"吗?不会,This is在这里只起了个控制符的作用. 即这句真正的意思是:让你输入"This is"后再输入变量C 也就是说This is是要你输入的,而scanf将忽略“This is”。

这样,再回到

scanf(" %d %d",&a,&b);我加了两个空格在%前,空格也是scnaf的控制符,它的意思就是过滤空格,回车,TAB,Newline等等空白符,也就解决你的问题。

3。getch()能解决问题,但是不是最佳的,请查看fflush函数用法及功能。

呵呵,我也只是一个初学者,所以思考得肯定不是很深.但对scanf("This is %d",&c),我的理解决对不 会像是你说的那样,写这样一行代码只是想说明一下应该如何输入才能正确地给C赋值

最后,感谢你的一些提示(空格也是scnaf的控制符,它的意思就是过滤空格,回车,TAB,Newline等等空白符).呵呵,这句话应该是最有价值的了.现在我已经知道利用scanf(" This is %d",&c)可以比较方便地实现输入了. 现在感觉,这篇文章可能有点乱了,不知道能不能给像我这样的人一点启发.建议还不能把握的朋友 自已多实践.再次感谢knocker大哥的帮助!

2004-09-09 18:46
快速回复:经验分享!!关于scanf()函数
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017637 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved