| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1215 人关注过本帖
标题:c语言do..while问题
只看楼主 加入收藏
thunder11102
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2012-3-29
收藏
得分:0 
回复 20楼 老高1
这不是从问题来学么?

虽然可能用不到,但也有助于更深的学习,真的不懂得话,那就先存着吧
2012-04-02 22:31
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
这个问题是这样的:

调用函数scanf("%d", &i),根据格式指示符"%d",scanf()预期从输入流中读取到1个int数据,当你的输入能够成功转化为需要的int数据时(比如你输入了100),它就把字符串"100"转换为整数100,并通过指针(&i)把整数赋给变量i,并且函数返回1,表示成功读取了1个数据(类似地,如果你写scanf("%d%d", &x, &y),则需要返回2才能表示成功读取了2个所需的数据,若返回1,只读得第1个,第2个是不成功的,若返回EOF,则是读到了用Ctrl+Z键入的流结束符)。

现在你继续输入"a",这是一个无法成功转化为int数据的字符,因此scanf()返回0表示不成功,而不再干预地址&i处的变量值,此时i仍为原先的100。但关键问题在scanf()函数会记忆上次的动作,它从上次返回的0中知道上次没读成,那么这次干脆不做动作(可以推测这个返回值是寄存在一个静态或全局变量中的;另外一种可能是scanf()仍然尝试去读"a",因为它上次并没有被从输入流中取走,霸在头位,所有接续scanf()都要先把它取走,而你又总不肯取字符或字符串。对后面这种可能性,在代码中没有办法预期后面可能有多少这样的东西,很难写预防代码,可以写一个读并废弃无效字符的循环来处理,但在现实各式各样需求的环境下,这种手法不大高明),于是,死循环出现了。

解决的办法是两个:第一,消除上次scanf()运行的返回结果(现在暂时不好处理);第二,重置变量i的值。所以,不妨采取如下办法:

程序代码:
int i;        // 如果你没有初始化,程序运行时会随机出现一个很巨大的整数,视内存变化而定,那就是你看到的那个大数
do
{
    i = 0;     // 此处初始化变量,回避随机值,也抛弃上次的值,给下面的if判断加一重保险,虽然可省,但写上不妨;若无下面判断,则必须有这个
    if (scanf("%d", &i) != 1)
    {
        break;
    }
    printf("af");
} while (i == 100);

在现代C++语言中,是不建议使用scanf()函数的,改用一个带有保险功能的替代函数scanf_s(),你如果使用VS C++编译器,它会出警告你改用scanf_s()函数,用那个会有更好的处理办法。

这个问题也给你一个教训:尽量避免在一个scanf()语句中读取多个数据,甚至是不同类型的数据,那种做法有多危险,你仔细琢磨一下现在这个问题就能感觉得出来。

[ 本帖最后由 TonyDeng 于 2012-4-2 23:39 编辑 ]

授人以渔,不授人以鱼。
2012-04-02 23:06
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 17楼 thunder11102
那个中文是因为你的系统是中文系统,系统会把一些能够解释成汉字的字符串内码认为是汉字,用汉字输出。当你用'\n'把两个连起来会误解的字符隔开,系统就不会把它们看成是汉字了。

注意:每个汉字是由两个ASCII字符并排组成的,只要两个字符(高位为1)并在一起,就可能被视为汉字。可以在程序指定系统的解释方案,不允许它这样做,你暂时没学到,这在“国际化”那一部分中。
收到的鲜花
  • thunder111022012-04-02 23:32 送鲜花  3朵   附言:好心人

授人以渔,不授人以鱼。
2012-04-02 23:17
thunder11102
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2012-3-29
收藏
得分:0 
回复 22楼 TonyDeng
版主你真好
还有一些问题需要请教
您加我的QQ吧
467035998

我睡觉了,可能没办法及时处理,不要介意
2012-04-02 23:20
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
刚才修改补充了一下22楼的帖子。我通常不加Q的,有什么在坛上说吧。

授人以渔,不授人以鱼。
2012-04-02 23:42
飞莲
Rank: 2
等 级:论坛游民
帖 子:42
专家分:64
注 册:2011-12-28
收藏
得分:5 
回复 8楼 thunder11102
通过scanf的返回值判断是不是成功读取了一个数字,不是的话就把后面的字符用scanf(“%*s”)略过。
你输入的字符会留在缓冲区被scanf一直读取,所以一直输出af
2012-04-03 00:27
chinaflag
Rank: 2
来 自:福建泉州
等 级:论坛游民
帖 子:46
专家分:83
注 册:2012-4-1
收藏
得分:0 
回复 19楼 thunder11102
这个没要必要偏偏要找错误吧,像这个东西错误原理是这样,但是深入了解还是很深奥的,建议楼主还是先把基础学好
2012-04-03 00:30
thunder11102
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2012-3-29
收藏
得分:0 
回复 26楼 飞莲
多谢指点....
2012-04-03 09:15
快速回复:c语言do..while问题
数据加载中...
 
   



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

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