能力值:
( LV12,RANK:660 )
|
-
-
2 楼
在我困惑时,这个fflush是一个大牛告诉我的,不过在不知道的时候还真是一头雾水~
|
能力值:
(RANK:300 )
|
-
-
3 楼
最初由 monkeycz 发布 高中搞NOI的时候用的是TC,深受一个问题困扰――scanf()函数为什么经常在取过一次用户输入后,就发疯似的不再停下来了。为这个问题,偶还专门请教过某高手,得到的不过是含糊其辞的托词。依稀记得这位高手还曾经教育过偶说win98刚启动起来的时候,不要随便乱动鼠标,否则鼠标的驱动程序会丢的 。从此之后,偶牢记奉行,98启动时再也不敢恣意的晃动鼠标了 。
当年的水平也就处于写写C代码,做做NOI题目(还经常做不出来)的水平上,更别提自己调试分析了。后来久而久之的就忘记掉这个问题了。不过后来时常在噩梦中与之相会,爽不堪言。
今天看到某一网站,居然无意中发现了问题的解决方法(http://www.china-askpro.com/msg14/qa80.shtml),一解多年来心头之埂。现把全文摘录如下: ........ 根据 ANSI C标准,和一些传统 C 的经验
1. C 语言的fflush 只是用作清除 output stream 之用。 对于使用 fflush 在 stdin 这个动作,是没有定义的行为
( ref: ISO/IEC 9899-1999 7.19.5.2 , ANSI Sec. 4.9.5.2 ) 2. 这个问题并不是 Turbo C 2.0 的 bug,这是标准 scanf 的正常行为。
Scanf 并不清理使用者输入的 newline character (0xa) ,在连续的 scanf 中如果参数字符串的第一个字是 % 参数 (for example: scanf(“%d”); ),它将会顺利地把 <last newline char><string> 读取,并且把 newline char 视作 white space,把它忽略。因此,在这个帖的代码 (修改前) 是可以正常运作。这是传统的 scanf 运用方法。
修改后的代码, scanf("i=%d j=%d",&i,&j); ,问题出现在参数字符串的开头是 ‘i=’ ,使 scanf 遇到最后一次 newline character 的时候便进行辨认,结果提前结束,返回错误。 这段程序的 i 和 j 不变,所以情形像 scanf 把上一次的数据读取一样,做成这个错误。
标准 scanf 本身的设计存在很多毛病,所以普遍建议是,不要采用 scanf,或是在 scanf 后作出完善的检查和处理。 3. 在这个情况,由于 fflush 不应该使用在 stdin 上,所以我们使用其它方法来解决,例如在 scanf 后面,加上一行 getchar(); ,把没有清理的 newline char 消除
printf("Please input num:");
scanf("i=%d j=%d",&i,&j);
getchar(); // clear newline
|
能力值:
(RANK:460 )
|
-
-
4 楼
原来如此。
|
能力值:
( LV5,RANK:60 )
|
-
-
5 楼
scanf("\ni=%d,j=%d",&i,&j);
也一样
|
能力值:
(RANK:300 )
|
-
-
6 楼
不可以
第一次scanf 的时侯 stdin 空白,没有 \n
我把你这句编译试验了,确实出错
|
能力值:
( LV5,RANK:60 )
|
-
-
7 楼
你的编译平台?
程序完整代码?
我在tc 2.01和vc 6.0 intel CPP8.01上正常编译
执行没有任何问题
|
能力值:
(RANK:300 )
|
-
-
8 楼
最初由 meilin 发布 你的编译平台? 程序完整代码?
我在tc 2.01和vc 6.0 intel CPP8.01上正常编译 执行没有任何问题 当然是使用原作者的代码,加上你这句
#include "stdio.h"
int main()
{
static int a[2][3]={{1,3,4},{7,9,6}};
int i,j,k;
for(k=1;k<=2;k++)
{
printf("Please input num:");
scanf("\ni=%d,j=%d",&i,&j);
if(i<2 && j<3)
printf("num=%d\n",a[i][j]);
else
printf("Input is error,\n");
}
printf("programm is complete.\n");
} 运行会出错
你试输入 i=0 j=1
|
能力值:
( LV5,RANK:60 )
|
-
-
9 楼
你应该输入i=0,j=1.
|
能力值:
(RANK:300 )
|
-
-
10 楼
原来把空格改了,所以出错
其实不把空格改成逗点,也可以顺利运作
scanf("\ni=%d j=%d",&i,&j);
看来只要把开头的第一个字玩设成 white space,便可以把 scanf 的参数扫瞄骗过
你试试这句
scanf(" i=%d j=%d",&i,&j);
i 前只用一个空格,也顺利运行了
|
能力值:
( LV5,RANK:60 )
|
-
-
11 楼
恩,就是给它一个它认为忽略的字符就ok
不过这样做已经在玩火.最好是老实
的在后面加getchar()
会读起来明朗点
|
能力值:
(RANK:300 )
|
-
-
12 楼
外国的 C 老手建议,在写一些需要安全性的程序时,使用 scanf 时要防止输入内存的 overflow 等等的问题,所以不再使用 scanf,使用较安全的 fgets + sscanf 代替
char buf[20]; // 指明我们的容许输入内存
…..
fgets( buf, 20, stdin ); // 限制只读取 20 位
sscanf( buf, "i=%d j=%d",&i,&j); // 把读取后的 buffer 进行扫瞄
这种手法可以保障安全,也可以同时解决 stdin 的 \n问题
|
能力值:
( LV4,RANK:50 )
|
-
-
13 楼
这个问题,以前也遇到过;
记得SCANF中的输入同参数是一一对应的关系就不会错了
|
能力值:
( LV9,RANK:810 )
|
-
-
14 楼
早在做一个dos程序时也遇到过这样的问题。
|
能力值:
( LV9,RANK:530 )
|
-
-
15 楼
riijj是C高手啊
|
能力值:
( LV8,RANK:130 )
|
-
-
16 楼
现在还看不懂,希望下个月能看懂
|
能力值:
( LV3,RANK:20 )
|
-
-
17 楼
不一定只有TC平台有这样的问题,换到VC平台也是这样的.
scanf("\ni=%d j=%d",&i,&j);中的"i="和"j="是不是用的有点多余
这种输入格式不是太常用吧
|
能力值:
( LV9,RANK:170 )
|
-
-
18 楼
点点滴滴都是时间+汗水凝聚而成呀
记下了!
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
记得哪个网站上说,scanf函数应该禁止使用。
好像标准C库函数中,有不少函数是bug函数。
|
|
|