能力值:
( LV12,RANK:660 )
|
-
-
2 楼
在我困惑时,这个fflush是一个大牛告诉我的,不过在不知道的时候还真是一头雾水~
|
能力值:
(RANK:300 )
|
-
-
3 楼
最初由 monkeycz 发布 高中搞NOI的时候用的是TC,深受一个问题困扰――scanf()函数为什么经常在取过一次用户输入后,就发疯似的不再停下来了 。为这个问题,偶还专门请教过某高手,得到的不过是含糊其辞的托词。依稀记得这位高手还曾经教育过偶说win98刚启动起来的时候,不要随便乱动鼠标,否则鼠标的驱动程序会丢的 。从此之后,偶牢记奉行,98启动时再也不敢恣意的晃动鼠标了 。
当年的水平也就处于写写C代码,做做NOI题目(还经常做不出来)的水平上,更别提自己调试分析了。后来久而久之的就忘记掉这个问题了。不过后来时常在噩梦中与之相会,爽不堪言。
今天看到某一网站,居然无意中发现了问题的解决方法(7b0K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4Z5K9h3&6S2i4K6u0V1j5i4y4C8M7s2u0G2i4K6u0W2j5$3!0E0i4K6u0r3L8i4y4Y4x3e0c8Q4x3V1k6I4j5e0R3H3i4K6u0W2M7$3S2@1L8h3I4Q4c8f1k6Q4b7V1y4Q4z5o6W2Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0c8Q4b7U0S2Q4z5o6m8Q4c8e0S2Q4b7e0N6Q4b7e0y4Q4c8e0g2Q4b7e0c8Q4z5f1q4Q4c8e0g2Q4b7U0W2Q4b7U0c8Q4c8e0k6Q4z5f1c8Q4b7e0g2Q4c8e0g2Q4b7V1k6Q4z5o6y4Q4c8e0g2Q4b7e0c8Q4b7U0c8Q4c8e0c8Q4b7U0W2Q4z5p5u0Q4c8e0g2Q4z5f1k6Q4z5o6u0Q4c8e0y4Q4z5o6m8Q4z5o6u0Q4c8e0N6Q4z5p5g2Q4b7U0m8Q4c8e0k6Q4z5p5q4Q4z5p5q4Q4c8e0g2Q4z5o6g2Q4b7e0S2Q4c8e0k6Q4z5e0k6Q4z5o6N6Q4c8e0k6Q4z5e0q4Q4z5e0S2Q4c8e0g2Q4b7V1c8Q4z5e0g2Q4c8e0g2Q4b7e0k6Q4z5o6u0Q4c8e0c8Q4b7U0S2Q4z5p5u0Q4c8f1k6Q4b7V1y4Q4z5f1p5`. ........ 根据 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函数。
|
|
|