当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 21 篇帖子 ]  前往页数 1, 2  下一页
作者 内容
1 楼 
 文章标题 : scanf,输入错误后,为什么不能再次输入?!
帖子发表于 : 2008-07-05 18:42 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
我的代码及运行情况如下

代码:
#include <stdio.h>
int main()
{
   int a, b;
   
   printf("enter:");
   int n = scanf("%d %d", &a, &b);
   if(n<2)
   {
      printf("err--n:%d\n", n);
      printf("enter:");
      //fflush(stdin);
      scanf("%d %d", &a, &b);
   }
   return 0;
}


执行情况:
代码:
    [zongzw@localhost stdin]$ a.out
    enter:1 2   
   
    [zongzw@localhost stdin]$ a.out
    enter:[b]1,[/b]
    err--n:1
    enter:[zongzw@localhost stdin]$


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2008-07-05 19:07 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
因为之前的东西被第二个scanf吃掉了


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2008-07-05 20:45 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
BigSnake.NET 写道:
因为之前的东西被第二个scanf吃掉了

那怎么才能不吃掉呢。


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2008-07-05 21:27 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
知道怎么弄了。
*参见这篇文章,http://blog.csdn.net/fxwzzbd/archive/2008/06/05/2514042.aspx

键盘输入缓冲区与scanf()原理。

键盘缓冲区用来缓存“按键”的ASCII码,而scanf()每次从键盘缓冲区中读取一个字符(ASCII码),直键盘缓冲区为空。如果键盘缓冲区为非空状态,执行scanf()不会要求输入,如果键盘缓冲区为空,执行scanf()则会等待用户的输入。
有时候我们可以在想要的输入之后添加一个scanf("%s", ch);来把标准输入中没有正确读入的信息读掉,清空标准输入。

代码:
#include <stdio.h>
#include <string.h>

int main()
{
   int a, b;
   int enough_len = 256;
   char ch[enough_len];
   memset(ch, 0, enough_len);
   printf("enter:");
   int n = scanf("%d %d", &a, &b);
   if(n<2)
   {
      scanf("%s", ch);
      printf("err--n:%d\n", n);
      printf("enter:");
      //fflush(stdin);
      scanf("%d %d", &a, &b);
   }
   return 0;
}


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2008-07-06 5:53 
头像

注册: 2007-03-13 11:23
帖子: 1343
送出感谢: 0 次
接收感谢: 0 次
zongzw 写道:
知道怎么弄了。
*参见这篇文章,http://blog.csdn.net/fxwzzbd/archive/2008/06/05/2514042.aspx

键盘输入缓冲区与scanf()原理。

键盘缓冲区用来缓存“按键”的ASCII码,而scanf()每次从键盘缓冲区中读取一个字符(ASCII码),直键盘缓冲区为空。如果键盘缓冲区为非空状态,执行scanf()不会要求输入,如果键盘缓冲区为空,执行scanf()则会等待用户的输入。
有时候我们可以在想要的输入之后添加一个scanf("%s", ch);来把标准输入中没有正确读入的信息读掉,清空标准输入。

代码:
#include <stdio.h>
#include <string.h>

int main()
{
   int a, b;
   int enough_len = 256;
   char ch[enough_len];
   memset(ch, 0, enough_len);
   printf("enter:");
   int n = scanf("%d %d", &a, &b);
   if(n<2)
   {
      scanf("%s", ch);
      printf("err--n:%d\n", n);
      printf("enter:");
      //fflush(stdin);
      scanf("%d %d", &a, &b);
   }
   return 0;
}

我一看到这个,这是我的第一反应。
C和C++的标准里从来没有定义过 fflush(stdin)。也许有人会说:“可是我用 fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(gcc3.2不支持),因为标准中根本没有定义 fflush(stdin)。MSDN 文档里也清楚地写着 fflush on input stream is an extension to the C standard (fflush 操作输入流是对C标准的扩充)。当然,如果你毫不在乎程序的移植性,用 fflush(stdin) 也没什么大问题。以下是 C99 对 fflush 函数的定义:

int fflush(FILE *stream); :em25


_________________
"We are all in the mud, but some of us are looking at the stars." (Oscar Wilde)
We are not born for ourselves.
人生天地间,并非为自己
Homepage:http://sites.google.com/site/polarisnotme/


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2008-07-06 9:38 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
thanks to kofshower,
说的很对,我在vc下实验fflush可以但是gcc下就不行了,我用的是gcc4.1,也是不支持fflush的。

于是、然后,scanf("%s",ch)掉多余的没有正确读入的字符就可以了。


页首
 用户资料  
 
7 楼 
 文章标题 :
帖子发表于 : 2008-07-06 9:38 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
还要考两科,没有写完,先看一下
http://hi.baidu.com/flyinflash/blog/ite ... 55915.html

代码:
int n = scanf("%d %d", &a, &b);

我不明白,你为什么会这样写,scanf 的返回值一般没有什么意义

概述:
不管是 scanf 还是 getchar,它们都不会接收 enter,
比如使用 scanf 接收输入
abc<-enter
则输入流为
abc\10(\10为回车)
但是scanf 仅认abc,\10会被下一个接收输入函数接收,所以会出现“跳过”的怪异情况

使用 getchar 接收输入
a<-enter
则输入流为
a\10
getchar 跟 scanf 一个样,不理 \10 的

代码:
#include <stdio.h>
int main()
{
   int a, b;
   
   a = getchar();
   b = getchar();
   
   printf("\n a = %d :: %c ", a, a);
   printf("\n b = %d :: %c ", b, b);
   return 0;
}


_________________
http://lee.youxu.info/


页首
 用户资料  
 
8 楼 
 文章标题 :
帖子发表于 : 2008-07-06 9:41 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
to flyinflash
我需要一次读入几个数据而不是1个数据啊,读入几个数据,并每次都敲一下回车,当然可以,我要得可不是这个效果。。,所以我会那样写:("%d %d", &a, &b)


页首
 用户资料  
 
9 楼 
 文章标题 :
帖子发表于 : 2008-07-06 9:46 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
解决方案

1、使用一个较长数组接收输入,把要的保留,不要的 \10 去掉。

但是,如果不知道哪些要,哪些不要,这个就不可行,与及,“较长“到底要多长?

2、自定义一个函数

我的博客里面没有写完 :D:D:D
http://hi.baidu.com/flyinflash/blog/ite ... 55915.html


_________________
http://lee.youxu.info/


页首
 用户资料  
 
10 楼 
 文章标题 :
帖子发表于 : 2008-07-06 10:05 
头像

注册: 2008-03-31 16:12
帖子: 94
送出感谢: 0 次
接收感谢: 0 次
好,好好借鉴一下


页首
 用户资料  
 
11 楼 
 文章标题 :
帖子发表于 : 2008-07-06 10:17 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
引用:
有时候我们可以在想要的输入之后添加一个scanf("%s", ch);来把标准输入中没有正确读入的信息读掉,清空标准输入。


思想和我的第一个解决方案有异曲同工之妙


代码:
NAME
       fflush - flush a stream

SYNOPSIS
       #include <stdio.h>
...
CONFORMING TO
       C89, C99.

NOTES
       Note that fflush() only flushes the user space buffers provided by  the
       C  library.   To  ensure that the data is physically stored on disk the
       kernel buffers must be  flushed  too,  for  example,  with  sync(2)  or
       fsync(2).


fflush 定义在 stdio 头文件里面,它是标准库的函数

但是,GCC 下工作得不是很好


_________________
http://lee.youxu.info/


页首
 用户资料  
 
12 楼 
 文章标题 :
帖子发表于 : 2008-07-06 10:19 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
我第一次遇到这个问题是在这里
一个小游戏

http://forum.ubuntu.org.cn/viewtopic.ph ... sc&start=0

里面就是使用第一种方案解决的,您看一下吧,说不定您能想到更的办法:D:D:D


_________________
http://lee.youxu.info/


页首
 用户资料  
 
13 楼 
 文章标题 :
帖子发表于 : 2008-07-06 10:32 
头像

注册: 2007-03-13 11:23
帖子: 1343
送出感谢: 0 次
接收感谢: 0 次
这个是我被培训的时候c/c++编程惯用法里面就提到这些东西,其实这有一个惯用的处理模式。
以c为例:这个惯用法同样适合stdin被重定向到文件的时候


附件:
window.png
window.png [ 73.83 KiB | 被浏览 1654 次 ]



_________________
"We are all in the mud, but some of us are looking at the stars." (Oscar Wilde)
We are not born for ourselves.
人生天地间,并非为自己
Homepage:http://sites.google.com/site/polarisnotme/


最后由 kofshower 编辑于 2008-07-06 18:05,总共编辑了 5 次
页首
 用户资料  
 
14 楼 
 文章标题 :
帖子发表于 : 2008-07-06 14:37 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
楼上的,你也太不专业了,竟然上图,而已是配色这么漂亮的图
给我拖出去打~~~


代码:
#include <stdio.h>

void flush()
{
   int c;
   
   while ((c = getchar() != '\n') && c != EOF) ;
}

int main(int argc, char** argv)
{
   int i, j;
   
   i = getchar();
   flush();
   j = getchar();
   
   putchar(i);
   putchar(j);
   
   return 0;
}


我建议把 flush 写进自定义的头文件里面

代码:
sudo mkdir /usr/include/lee
sudo chown lee:lee /usr/include/lee
touch /usr/include/lee/stdiol.h



代码:
#ifndef __STDIOL_H__
#define __STDIOL_H__

#include <stdio.h>
#include <stdlib.h>


int getch(void)
{
  int key;
 
  system("stty raw");
  //  stty - change and print terminal line settings
  //  raw - same as -ignbrk -brkint -ignpar -parmrk  -inpck  -istrip  -inlcr
 
  key = getchar();
 
  system("stty cooked");
  //  cooked - same  as  brkint ignpar istrip icrnl ixon opost isig icanon,
  //           eof and eol characters to their default values
 
  return key;
}


void flush()
{
   int c;
   
   while ((c = getchar() != '\n') && c != EOF) ;
}


#endif


_________________
http://lee.youxu.info/


页首
 用户资料  
 
15 楼 
 文章标题 :
帖子发表于 : 2008-07-06 14:39 
头像

注册: 2006-09-21 14:28
帖子: 2376
送出感谢: 0 次
接收感谢: 0 次
代码:
#include <stdio.h>
#include <lee/stdiol.h>

int main(int argc, char** argv)
{
   int i, j;
   
   i = getchar();
   flush();
   j = getchar();
   
   printf("\n");
   
   putchar(i);
   putchar(j);
   
   printf("\n");
   
   return 0;
}


代码:
1alee@lee-thinkpad:/tmp$ ./t
128391
salkdflasf

1s
lee@lee-thinkpad:/tmp$


_________________
http://lee.youxu.info/


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 21 篇帖子 ]  前往页数 1, 2  下一页

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译