一个奇怪的C语言问题

yangt1100 2010-08-31 11:02:23

main()
{
int num1;
char c;

scanf("%d",&num1);
printf("num1=%d\n",num1);

scanf("%c",&c);
printf("%c\n",c);
}


这段代码有什么问题?应该没有吧!但无论是在VC还是在TC下,执行到第二个scanf
时就会退出。请高手指教!如果把代码改一下,把最后两句语句提到前面就可以正常
执行了了。代码如下:

main()
{
int num1;
char c;

scanf("%c",&c);
printf("%c\n",c);

scanf("%d",&num1);
printf("num1=%d\n",num1);
}



不知道这是C语言的BUG还是C语言里面的规定?
...全文
278 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhaiershuaixu 2010-09-01
  • 打赏
  • 举报
回复
加个getchar()就可以。
  • 打赏
  • 举报
回复
清空缓存吧。。。。。。。。。这个问题不太好解释。。。。 为什么 输入整型数 浮点数的时候不会出现这样的情况,而字符就会出现。。。。。。。。这确实难解释。。。。。。
Hoolala 2010-09-01
  • 打赏
  • 举报
回复
如一楼所说,你在程序后面加getchar(); 或者system("pause");就不会莫名奇妙退出了
红烧肉 2010-09-01
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 for1096 的回复:]

引用 8 楼 t_fast 的回复:
借贵宝地一用
问个问题,char 转int 怎么转? 高位补0? 比如 char 11111111 转 int 0000000011111111 ?

高位补0,然后再把符号位补上。(char是带符号的)
[/Quote]
吹个牛,如果是char转int的话,int的高位是以char的符号位(最高位)来补的
for1096 2010-09-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 t_fast 的回复:]
借贵宝地一用
问个问题,char 转int 怎么转? 高位补0? 比如 char 11111111 转 int 0000000011111111 ?
[/Quote]
高位补0,然后再把符号位补上。(char是带符号的)
周靖峰 2010-09-01
  • 打赏
  • 举报
回复
楼主应该这么写

main()
{
int num1;
char c;

scanf("%d%*c",&num1);
printf("num1=%d\n",num1);

scanf("%c%*c",&c);
printf("%c\n",c);
}

%*c用来接收多余的回车键
向立天 2010-09-01
  • 打赏
  • 举报
回复
老版的有关字符串处理C运行时库本来安全性就差些
所以现在都建议使用_s版的
bobo364 2010-09-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yangt1100 的回复:]
事实正如前面几楼说的!感觉这就是C语言的一个BUG吧。比方说scanf("%d%c",&num,&c);按照C语言的语法,输入的时候我们一般是这样输入12 a 但这样的话c的值就不会等于a而是等于空格的ASIC值,如果输入12a的话C语言会将num的值赋为12 而c=a。但我奇怪的是编译器为什么不会将12a的值赋给num呢?
[/Quote]

所以到c++里才有了那个样子的输入
a281458177 2010-09-01
  • 打赏
  • 举报
回复
学习一下
wizard_tiger 2010-09-01
  • 打赏
  • 举报
回复
九楼正解!
dingshaofengbinbin 2010-09-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 we_sky2008 的回复:]
程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而scanf函数直接从输入缓冲区中取数据。正因为scanf函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,scanf函数会直接取得这些残留数据而不会请求键盘输入,这就是例子中为什么会出现输入语句失效的原因!
scanf()和getchar()函数是从输入流缓冲区中读取值……
[/Quote]
正解!!!
walkersfaint 2010-09-01
  • 打赏
  • 举报
回复
清空缓冲区应该就可以的
FengRider 2010-09-01
  • 打赏
  • 举报
回复
以前也见过别人提过类似的问题,不过都是因为缓冲区在下一个scanf之前未清空造成的。第二次使用scanf时,要保证缓冲区已经被清空,否则会接收到未知的字符。
we_sky2008 2010-09-01
  • 打赏
  • 举报
回复
程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而scanf函数直接从输入缓冲区中取数据。正因为scanf函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,scanf函数会直接取得这些残留数据而不会请求键盘输入,这就是例子中为什么会出现输入语句失效的原因!
scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。而读取时遇到回车(\n)而结束的,这个\n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符\n,这样第二次的读入函数直接从缓冲区中把\n取走了,显然读取成功了,所以不会再从终端读取!这就是为什么这个程序只执行了一次输入操作就结束的原因
szjeff2005 2010-09-01
  • 打赏
  • 举报
回复
scanf会根据你的输入条件来进行解释,如%d是会以空格,回车以及TAB为边界的,读了后直接将指针跳过边界,而%c则不会,所有的边界值对它而言都是ASCII码,都可以进行读取。所以用scanf时要谨慎,所见不一定是所得
luciferisnotsatan 2010-09-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yangt1100 的回复:]

事实正如前面几楼说的!感觉这就是C语言的一个BUG吧。比方说scanf("%d%c",&num,&c);按照C语言的语法,输入的时候我们一般是这样输入12 a 但这样的话c的值就不会等于a而是等于空格的ASIC值,如果输入12a的话C语言会将num的值赋为12 而c=a。但我奇怪的是编译器为什么不会将12a的值赋给num呢?
[/Quote]

建议楼主自己跟到scanf里看下就知道了。%d%c你的格式化字符串当中没空格。赋值时自然会把12后面的字符“空格”赋给c了。%d是10进制,a不在取值范围内。但如果你用%x 16进,那就会把12a赋给num了。
cobra_chen 2010-09-01
  • 打赏
  • 举报
回复
C语言用SCANF对字符串或字符支持很不好。
你要继续用,还会发现一些奇怪的问题呢。

需要用最好用
getchar() or gets()
putchar() or puts()
t_fast 2010-08-31
  • 打赏
  • 举报
回复
借贵宝地一用
问个问题,char 转int 怎么转? 高位补0? 比如 char 11111111 转 int 0000000011111111 ?
libinfei8848 2010-08-31
  • 打赏
  • 举报
回复
使用scanf函数时应该注意的问题

  1、scanf()中的变量必须使用地址。 
  2、scanf()的格式控制串可以使用其它非空白字符,但在输入时必须输入这些字符。
  3、在用"%c"输入时,空格和“转义字符”均作为有效字符。
  • 打赏
  • 举报
回复
换行符'\n'也是一个字符,第一种是因为缓冲区还有一个回车换行符'\n',于是c就理所当然的接受了


第二种%d与换行符'\n'或者空格符等不同类型,会直接丢掉,直到有正确的数据或能够转化的数据输入!
加载更多回复(5)

69,372

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧