| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4743 人关注过本帖
标题:关于scanf 输入数据与接收数据类型不同时产生的问题
只看楼主 加入收藏
Alien_Lee
Rank: 8Rank: 8
来 自:Linux帝国
等 级:蝙蝠侠
威 望:7
帖 子:149
专家分:739
注 册:2016-7-19
结帖率:83.33%
收藏
已结贴  问题点数:10 回复次数:9 
关于scanf 输入数据与接收数据类型不同时产生的问题
我用一个int型的变量去接收一个数据,接收格式设置为%d。我的环境为vs2013
程序代码:
#define _CRT_SECURE_NO_DEPRECATE
# include <stdio.h>
#include<stdlib.h>
#define see system("pause")
void main()
{
    int i=0;
    int n = 12;//循环次数
    while (n--){
        scanf("%d",&i);
        printf("i=%d\n", i);
    }
    see;
}
当我正常输入数字时是正常的,当我输入一个数字,显示一个数字。
但是当我输入的数据不是数字的时候,比如“w”,就成了无限输出上一个正确的数字,而不再提供输入(scanf失效),请问这是为什么?
图片附件: 游客没有浏览图片的权限,请 登录注册


我猜测可能是输入数据流的问题,所以我就刷新了一下输入数据流
程序代码:
#define _CRT_SECURE_NO_DEPRECATE
# include <stdio.h>
#include<stdlib.h>
#define see system("pause")
void main()
{
    int i=0;
    int n = 12;
    while (n--){
        scanf("%d",&i);
        printf("i=%d\n", i);
        fflush(stdin);
    }
    see;
}
此时,scanf有效,提供输入口,但是如果你输入的是非数字,比如“w”,它还是不能读入w,输出原有最后一次的正确数。
图片附件: 游客没有浏览图片的权限,请 登录注册


请问这是什么原因,scanf对格式错误的数据的处理方式是什么?
搜索更多相关主题的帖子: system 
2016-09-09 10:36
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
需要人为控制

DO IT YOURSELF !
2016-09-09 10:58
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
但是当我输入的数据不是数字的时候,比如“w”,就成了无限输出上一个正确的数字,而不再提供输入(scanf失效),请问这是为什么?
因为那个w没被scanf读走,他还在缓存器里面,所以你的scanf就永远只能读到w,所以就无限循环了。ffulsh()也行、getchar()等等其他方式也行,关键是把缓存器里的那个w给弄走就可以了
scanf("...",...)  函数会返回一个int表示这一次总共读到了多少个有效的值。可以用这个值来和我们希望它能读到的变量个数做比较,从而进一步处理冲突。
程序代码:
#define _CRT_SECURE_NO_DEPRECATE
# include <stdio.h>
#include<stdlib.h>
#define see system("pause")
void main()
{
    int i=0;
    int n = 12;//循环次数
    while (n--){
        if(scanf("%d",&i)!=1){
            char temp;
            if(scanf(“%c”,&temp)!=-1)
            printf("%c 不是一个有效的输入!\n",temp);
            else printf("输入结束\n");
         }else printf("i=%d\n", i);
    }
    see;
}
scanf()==-1或者EOF 时表示输入流已经关闭,或者已经读到了文件的末尾。scanf()==0表示没有读到任何一个有效的值,但不表示后面不会有更多的输入。
测试我给出的代码
在windows的工作环境中,你可以通过   (回车)Ctrl+Z(回车)   来让程序得到这个-1
  Linux      的我忘了,你可以百度一下,或者翻翻论坛,这个问题蛮多人遇到的      





[此贴子已经被作者于2016-9-9 12:20编辑过]


φ(゜▽゜*)♪
2016-09-09 11:24
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:0 
if(scanf(“%c”,&temp)!=-1)不要这样用。如果非要这样用就将temp改成int类型,而不是char类型
2016-09-09 11:45
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
回复 4楼 linlulu001
为什么?
程序运行到要scanf(temp)的时候已经确定那不可能会是个int了啊


[此贴子已经被作者于2016-9-9 12:20编辑过]


φ(゜▽゜*)♪
2016-09-09 12:19
Alien_Lee
Rank: 8Rank: 8
来 自:Linux帝国
等 级:蝙蝠侠
威 望:7
帖 子:149
专家分:739
注 册:2016-7-19
收藏
得分:0 
回复 3楼 书生牛犊
您给的这个修改方法,还是有一个bug:当你输入符号“+”的时候,scanf收到的是回车符,而不是“+”,其他的符号正常,请问这是什么原因呢?
程序代码:
#define _CRT_SECURE_NO_DEPRECATE
# include <stdio.h>
#include<stdlib.h>
#define see system("pause")
void main()
{
    int i = 0;
    int n = 12;//循环次数
    while (n--){
        if (scanf("%d", &i) != 1){
            if (scanf("%c", &i) != EOF)
                printf("%c 不是一个有效的输入!\n", i);
            else
                pritf("error\n");
        }
        printf("i=%d\n", i);
    }
    see;
}

图片附件: 游客没有浏览图片的权限,请 登录注册


  DEBUG的过程就是进步的过程,每一个小错误都是大问题!...
2016-09-09 12:39
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:8 
回复 6楼 Alien_Lee
我在某次做题目的时候也踩到这个坑了,不仅仅是+,还有-

原因是  +-  在读%d的时候程序默认他是正负号,所以就把他读了,可是当他读下一个字符的时候后面没有数字,这时候就知道他不是正负号了,所以%d还是没读到值,只不过缓存器里面的+-已经被读走了,还不回去。这个时候留在缓存器里面的就会是回车了。


讲到这个回车就不得不提另外一件事,scanf(...)除了%c这个函数是会自动跳过前导空白符(比如回车换行空格制表符),像这个例子中的每一次scanf(%d)之后,缓存器中的数字被读走,但是还是会留下一个'\n',而这个'\n'则会在下一次scanf(%d)的时候被当做前导空白符忽略掉。而scanf(%c)是读一个字符,空格、回车换行啥的他全部都能当做一个字符读。
所以你输入“+”的那一轮已经发生了两件事:scanf(%d)==0,加号被读走了;scanf(%c),读到了'\n'.

φ(゜▽゜*)♪
2016-09-09 12:57
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
如果你觉得我讲的有点绕,建议你   百度一下“scanf()”,然后找一些博客文章看看。

他们会分析得比较具体,条理也会很清晰,然后也会讲到很多我没讲到的东西。

φ(゜▽゜*)♪
2016-09-09 12:59
linlulu001
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:20
帖 子:944
专家分:4047
注 册:2016-4-13
收藏
得分:2 
回复 5楼 书生牛犊
if(scanf(“%c”,&temp)!=-1),是我考虑欠缺。这里用的是scanf,可以这样用。
2016-09-09 13:42
Alien_Lee
Rank: 8Rank: 8
来 自:Linux帝国
等 级:蝙蝠侠
威 望:7
帖 子:149
专家分:739
注 册:2016-7-19
收藏
得分:0 
回复 7楼 书生牛犊
您的回答很详细,非常感谢!!!

  DEBUG的过程就是进步的过程,每一个小错误都是大问题!...
2016-09-09 14:41
快速回复:关于scanf 输入数据与接收数据类型不同时产生的问题
数据加载中...
 
   



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

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