LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1162|回复: 9

如何清空stdin

[复制链接]
发表于 2003-9-30 21:35:28 | 显示全部楼层 |阅读模式
# include <stdio.h>

/* 功能说明:返回获取的一个击键ASCII值,且无论击键多少次,都只返回第一个击键。*/
int getcommand (void)
{
                char s[2];
                int c;
                fread (s, sizeof(char)*2, 1, stdin);
                c = s[0];
                return c;
}

int main (void)
{
        int counter=0, ascii;
        while (1){
                counter++;
                ascii = getcommand();
                printf ("loop: %d\n", counter);
        }
        return 0;
}

出现问题

事实上,循环的次数是按键次数的n-1(因为回车也算一个),也就是说,当循环第一次执行的时候,fread()会等待输入,并且它执行一次只取二个字符,当输入的字符数大于2时,getcommand()函数再次执行时会读取上次“剩下”的按键,我是我所不希望的,我要的是每次执行getcommand()函数,fread()都停下来等待使用者的输入。

我有一个思路,就是每执行完毕之后,都把stdin里面的内容清空,这样下次执行时fread()就会停下来等待新的输入了,但我不知道如何做,请大家帮帮忙。
 楼主| 发表于 2003-9-30 21:37:05 | 显示全部楼层
不好意思,刚才贴代码的时候没有用到代码模式:(
大家看的时候可能要多费点心。
发表于 2003-9-30 21:55:25 | 显示全部楼层

  1. int getcommand (void)
  2. {
  3.     int s[1] = {0};
  4.     int c;
  5.     fread (s, 1, 1, stdin);
  6.     while( c = getchar() != '\n' && c != EOF)  // 用 getchar 来消耗多余的字符
  7.         ;
  8. return s[0];
  9. }
复制代码

希望你喜欢。
 楼主| 发表于 2003-9-30 22:04:51 | 显示全部楼层
谢谢,总算把问题解决了。
本来可以用gets(),但受到gcc的警告,我想可能是由于gets()不能控制读入数据量这个原因吧。
发表于 2003-9-30 22:10:19 | 显示全部楼层
永远不要使用 gets, 那是噩梦的开始,基本常识。
gets 的缓冲区很小,大概 500 字节,别有用心的人精心设计的数据,很容易使缓冲区溢出。溢出后他就得到了这个程序的权限,如果是系统权限的话,我想后果你也能够猜到。
gcc 提示也就是这个目的,良好习惯是使用 fgets,因为它带数据大小参数,比较安全。
 楼主| 发表于 2003-9-30 22:48:43 | 显示全部楼层
哦!以后“永远”记住了。
发表于 2003-10-1 11:45:38 | 显示全部楼层
fflush(NULL);
 楼主| 发表于 2003-10-1 12:03:10 | 显示全部楼层
高兴ing
又知道了一种方法。
发表于 2003-10-1 12:46:38 | 显示全部楼层
看它的man
详是可以只flash指定的文件描述符的

不过单是fflash(stdin或是fflush stdout一般不会成功(我是没有成功过)
所以还是使用fflash(NULL进行全部刷新
发表于 2003-10-1 13:37:18 | 显示全部楼层
fflush(stdout)
是把 stdout 缓冲区的内容写到和 stdout 关联的文件,不符合要求。
fflush(stdin)
是未定义行为,不要使用。除非你已经知道使用的编译器特意把 fflush(stdin) 声明为刷新缓冲区,这是没法阻止的,不过结果是没法移植。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表