热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c语言防止getchar吞字符,问一个关于getchar()吃回车的问题~!(初学者)

刚刚在看到的一篇文章,希望能有所帮助。CC误区二——fflush(stdin)1.为什么fflush(stdin)是错的首先请看以下程序:#includ

刚刚在看到的一篇文章, 希望能有所帮助 。

C/C++ 误区二

—— fflush(stdin)

1. 为什么 fflush(stdin) 是错的

首先请看以下程序:

#include

int main( void )

{

int i;

for (;;) {

fputs("Please input an integer: ", stdout);

scanf("%d", &i);

printf("%d\n", i);

}

return 0;

}

这个程序首先会提示用户输入一个整数,然后等待用户输入,如果用户输入的是整数,程序会输出刚才输入的整数,并且再次提示用户输入一个整数,然后等待用户输入。但是一旦用户输入的不是整数(如小数或者字母),假设 scanf 函数最后一次得到的整数是 2 ,那么程序会不停地输出“Please input an integer: 2”。这是因为 scanf("%d", &i); 只能接受整数,如果用户输入了字母,则这个字母会遗留在“输入缓冲区”中。因为缓冲中有数据,故而 scanf 函数不会等待用户输入,直接就去缓冲中读取,可是缓冲中的却是字母,这个字母再次被遗留在缓冲中,如此反复,从而导致不停地输出“Please input an integer: 2”。

也许有人会说:“居然这样,那么在 scanf 函数后面加上‘fflush(stdin);’,把输入缓冲清空掉不就行了?”然而这是错的!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);

如果stream指向输出流或者更新流(update stream),并且这个更新流 鐽巃劖]?? 最近执行的操作不是输入,那么fflush函数将把任何未被写入的数据写入stream 茘-秛驨尔 指向的文件(如标准输出文件stdout)。否则,fflush函数的行为是不确定的。 5p>洿[杫x? fflush(NULL)清空所有输出流和上面提到的更新流。如果发生写错误,fflush 肽稨撶*)"` 函数会给那些流打上错误标记,并且返回EOF,否则返回0。

由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin) 是不正确的,至少是移植性不好的。

2. 清空输入缓冲区的方法

虽然不可以用 fflush(stdin),但是我们可以自己写代码来清空输入缓冲区。只需要在 scanf 函数后面加上几句简单的代码就可以了。

/* C 版本 */

#include

int main( void )

{

int i, c;

for (;;) {

fputs("Please input an integer: ", stdout);

scanf("%d", &i);

/* while循环会把输入缓冲中的残留字符清空 */

/* 读者可以根据需要把它改成宏或者内联函数 */

/* 注:C99中也定义了内联函数,gcc3.2支持 */

while ( (c=getchar()) != '\n' && c != EOF ) {

;

} /* end of while */

printf("%d\n", i);

}

return 0;

}

/* C++ 版本 */

#include

#include // 为了使用numeric_limits

using std::cout;

using std::endl;

using std::cin;

int main( )

{

int value;

for (;;) {

cout <<"Enter an integer: ";

cin >> value;

/* 读到非法字符后&#xff0c;输入流将处于出错状态&#xff0c;

* 为了继续获取输入&#xff0c;首先要调用clear函数

* 来清除输入流的错误标记&#xff0c;然后才能调用

* ignore函数来清除输入缓冲区中的数据。 */

cin.clear( );

/* numeric_limits::max( ) 返回缓冲区的大小。

* ignore 函数在此将把输入缓冲区中的数据清空。

* 这两个函数的具体用法请读者自行查询。 */

cin.ignore( std::numeric_limits<:streamsize>::max( ), &#39;\n&#39; );

cout <

}

return 0;

}

参考资料&#xff1a;ISO/IEC 9899:1999 (E) Programming languages — C 蚣狵岅覺啁 7.19.5.2 The fflush function

The C Programming Language 2nd Edition By Kernighan & Ritchie

ISO/IEC 14882(1998-9-01)Programming languages — C&#43;&#43;



推荐阅读
  • 题目描述Takuru是一名情报强者,所以他想利用他强大的情报搜集能力来当中间商赚差价。Takuru的计划是让Hinae帮他去市场上买一个商品,然后再以另一个价格卖掉它。Takur ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • golang源码分析调度概述
    golang源码分析-调度过程概述本文主要概述一下golang的调度器的大概工作的流程,众所周知golang是基于用户态的协程的调度来完成多任务的执行。在Linux ... [详细]
  • 一文了解Python collections模块中的deque用法[python头条资讯]
    Python中文网有大量免费的Python入门教程,欢迎大家来学习。collections是Python内建的一个集合模块,deque是双边队列,具有队列和栈的性质,在list的基 ... [详细]
  • VS用c语言连接mysql,c语言连接mysql完整演示
    #include#includeintmain(){MYSQL*conn;创建一个指向mysql数据类型的指针connmysql_init(NULL);mysql的初始化if(!c ... [详细]
  • 796.[APIO2012]派遣在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。在这个帮派里,有一名忍者被称之为Master。 ... [详细]
  • 题面传送门Solution看到什么最大值最小肯定二分啊。check直接跑一个二分图匹配就好了。orzztl!!!代码实现*mail:mle ... [详细]
  •   并查集是一种群众喜闻乐见的数据结构,其复杂度是数据结构中最奇葩的之一了,Tarjan证明其为阿克曼函数的反函数,在可以想象(不全面的解释啊)的范围内小于等于3。。。我们就把它当做O(1)吧。下面通 ... [详细]
author-avatar
超级冷笑话驿站料_663
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有