| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3372 人关注过本帖
标题:连续两个scanf()遇到的新问题!看清!不关回车符的事!
只看楼主 加入收藏
jzhur0726
Rank: 2
等 级:论坛游民
威 望:1
帖 子:13
专家分:30
注 册:2016-8-2
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:6 
连续两个scanf()遇到的新问题!看清!不关回车符的事!
网上看到一篇"C语言scanf函数输入时键盘缓冲区\n的问题"博文
http://blog.
试了第一个例子就试出问题来了!
以下是原文:
/***********************************************************
程序1
#include "stdio.h"
void main()
{
 char a;
 char b;
 scanf("%d",&a);
 scanf("%d",&b);
 printf("%d %d",a,b);
}
键盘输入
97<回车>96<回车>
输出
97 96
问题1:调用第一个scanf输入时,键盘缓冲区所有的字符为97\n,
遇到回车,所以缓冲区把97赋值给a。调用第二个scanf输入时,
键盘缓冲区所有的字符为96\n,遇到回车,所以缓冲区把96赋值给b。
以上我的分析对吗?
*************************************************************/
//以下是正文:
#include <stdio.h>
int main(void)
{
    int i;
    char a,c;
   
    i=scanf("%d", &a);
    scanf("%d", &c);
    printf("a=%d\t", a);
    printf("c=%d\t", c);
    printf("i=%d\n", i);

    return 0;
}
/*
在 gcc + notepad++ 中的运行结果为:
*****************************************
34
67
a=      c=C     i=0
67
87
a=0     c=87    i=0
56
79
a=0     c=79    i=2
*****************************************
*/
第一次:输出用%c
第二次:输出用%d
第三次:输出用%d,但把两次输入放在一个scanf()中了。
在ASCII中,十进制数与字符对应关系为:34=" 67=C 56=8。
前两次,i=0,很明显,没有给a赋值,但是,在手机C4droid上试了下,a的情况没变,i值却变成1,显示读取数据成功
第三次,i=2,显示两次都成功读取数据,但是,a的情况却没变化。
新手,就20分,都给了!望大神给解惑啊!
附图一张
图片附件: 游客没有浏览图片的权限,请 登录注册

搜索更多相关主题的帖子: include 缓冲区 C语言 键盘 
2016-08-18 17:24
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
因为int型占4字节,char型占1字节,导致往char地址中输入整型数溢出修改了其它地址的数据。
2016-08-18 20:06
jzhur0726
Rank: 2
等 级:论坛游民
威 望:1
帖 子:13
专家分:30
注 册:2016-8-2
收藏
得分:0 
谢谢大神回复
可以具体些吗?我也意识到了是数据溢出,但不太清楚详细过程!
后来我又试了一次,把例题程序1中 a 和 b 的函数定义顺序互换了一下,这次得到了正确的输出。
 char b;
 char a;
 scanf("%d",&a);
 scanf("%d",&b);
 printf("%d %d\n",a,b);
/*
65
78
65 78
*/
后来又把其中一个scanf函数注释掉,输出时 a = 0 或 b = 0。
按理说,未初始化变量输出为垃圾值,现在输出一直为0,应该是被溢出数据覆盖了。
 char b;
 char a;
 scanf("%d",&a);
 // scanf("%d",&b);
 printf("%d %d\n",a,b);
/*
67
67 0
*/
2016-08-19 01:10
zx315
Rank: 5Rank: 5
来 自:广东
等 级:职业侠客
威 望:2
帖 子:86
专家分:378
注 册:2016-7-13
收藏
得分:7 
程序代码:
printf("%p\n", &a);
printf("%p\n", &c);
printf("%p\n", &i);


把它们的地址打印出来后,结果一目了然~

Read The Fucking Source Code~
2016-08-19 13:14
ehszt
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:40
帖 子:1745
专家分:3216
注 册:2015-12-2
收藏
得分:0 
以下是引用zx315在2016-8-19 13:14:41的发言:


printf("%p\n", &a);
printf("%p\n", &c);
printf("%p\n", &i);


把它们的地址打印出来后,结果一目了然~

楼上是个好方法,这样你就可以看他们地址谁大谁小,肯定是小的覆盖大的(前面覆盖后面的)。
2016-08-19 17:55
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:7 
问题1:调用第一个scanf输入时,键盘缓冲区所有的字符为97\n,
遇到回车,所以缓冲区把97赋值给a。调用第二个scanf输入时,
//到这里是对的,但是\n并没有被读走,他还在缓冲区
键盘缓冲区所有的字符为96\n,遇到回车,所以缓冲区把96赋值给b。//这里独到的是\n(scanf()函数会自动省略开头的回车、换行、空格、制表符等控制符号)96\n,然后96被赋 值,而又留了一个\n在缓存区,前面那个被省略掉的\n是真的消失了,这时候的缓存区就只有一个\n,不信你可以在这两句scanf()的后面加一个scanf(%c),就可以读到那个\n了。未来在做题目的时候经常会遇到这种因为缓存区残留空白符而导致的出错。
以上我的分析对吗?

[color=#000033]C语言用于读数据的函数还有get()getchar(),这两个都不会省略掉开头遇到的空白符,get()一次读一行,遇到回车符才停止,并在回车符的那个位置写入\0,而他不会留一个\n在缓存区,getchar()读一个字符,什么字符都能读。
[/color]

φ(゜▽゜*)♪
2016-08-20 14:29
jzhur0726
Rank: 2
等 级:论坛游民
威 望:1
帖 子:13
专家分:30
注 册:2016-8-2
收藏
得分:0 
谢谢各位大神!后来试了下, 的确按入栈的规则,先定义的变量地址在后定义的后面,一般如果输入一次就输出一次是不会发现出错的,但第二次一起输出就会发现错误
2016-08-23 16:22
快速回复:连续两个scanf()遇到的新问题!看清!不关回车符的事!
数据加载中...
 
   



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

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