题目

输入一个整数n,接下来n行每一行输入两个用一个空格分隔的字符。

对每一对字符,比较其大小关系并输出比较的结果:1、0、-1.

解决的代码如下:

#include<stdio.h>

int main()
{
int N,i;
char c1=' ',c2=' ';
scanf("%d",&N);
getchar();
for(i=;i<N;i++)
{
scanf("%c %c",&c1,&c2);
getchar();
if(c1>c2) printf("1\n");
else if(c1<c2) printf("-1\n");
else printf("0\n");
}
return ;
}

这个地方最需要注意的是char变量其实在输入时读取的是键盘缓冲区的内容。上面的写法只是一个变通的写法,安全的写法是清空键盘缓冲区的内容。

参见:http://bbs.bccn.net/thread-248420-1-1.html

清空键盘缓冲区的一种好方法!

用  rewind(stdin);  语句可以达到很好的清空键盘缓冲区的作用。不用考虑太多其他因素。这是我在一本名为《软件开发:编程与设计(C语言版)》中所了解到的,作者是USA的David Conger。
    以前也了解到其他的清空键盘缓冲区的方法,如:用getchar();fflush(stdin);等。但感觉很麻烦,不好用,也不容易理解。而rewind(stdin)简单好用,而且是一种可移植的方法。

举个例子:

 #include <stdio.h>

 int main()
{
int i;
char aString[]; printf("Please enter some characters:"); /*先向键盘缓冲区里输入无用字符*/ getchar(); rewind(stdin); /*清空键盘缓冲区里的无用字符*/ printf("Please enter 'OK': "); /*输入字符串“OK”*/ for(i=;i<;i++) /*字符串aString接受字符串“OK”*/
{
aString[i]=getchar();
}
aString[i]='\0'; puts(aString); /*输出字符串aString*/ return();
}

Microsof Visual C++下调试结果:

输入:abcdefghijk回车OK回车
输出:OK

之前缓冲区里的abcdefghijk垃圾字符都被清空了。

下面向新手解释一下rewind(stdin);的工作原理。

C语言把键盘,显示器等设备当做文件来处理,也就是说从键盘输入相当于从一个文件中读入,向显示器输出相当于向一个文件写出。
而stdin是C标准库定义的标准文件之一,它与键盘相关联。我一般把它理解为指向键盘这个“文件”的指针。
而rewind()函数的作用是把文件的当前位置指针指向文件头。
两者结合,rewind(stdin);的作用也就是把“指向键盘(一个文件)的指针从当前位置挪到键盘(一个文件)开头”,相当于抛弃了当前键盘缓冲区中的数据,重新开始输入。
虽然并不是真正的把缓冲区里的数据全部清掉,但却起到了清空键盘缓冲区的作用。

也可参考:http://blog.sina.com.cn/s/blog_63c66eb60100sc0o.html

空键盘缓冲区很多种方法,如用fflush(stdin); rewind(stdin);setbuf(stdin, NULL);前两者仅对windows有用,最后一个则对Linux系统也适用。那么为什么需要清空键盘缓冲区呢?

以下几个实例:

Sample one

 #include <stdio.h>
int main()
{
char ch1;
char ch2;
ch1 = getchar();
ch2 = getchar();
printf("%d %d", ch1, ch2);
return ;
}
 

程序的本意很简单,就是从键盘读入两个字符,然后打印出这两个字符的ASCII码值。可是执行程序后会发现出了问题:当从键盘输入一个字 符后,就打印出了结果,根本就没有输入第二个字符程序就结束了。例如用户输入字符’a', 打印结果是97,10。这是为什么呢?

【分析】:

scanf()和getchar()函数是从输入流缓冲区中读取值的,而并非从键盘(也就是终端)缓冲区读取。而读取时遇到回车(n)而 结束的,这个n会一起读入输入流缓冲区的,所以第一次接受输入时取走字符后会留下字符n,这样第二次的读入函数直接从缓冲区中把n取走了,显然读取成功 了,所以不会再从终端读取!其实这里的10恰好是回车符!这就是为什么这个程序只执行了一次输入操作就结束的原因!

【解决办法】:

清空缓冲区的残留数据。

使用 fflush(stdin); 或 rewind(stdin); 均可起到清空键盘缓冲区的作用,这两个函数均包含在stdio.h这个头文件中

修正后的写法:
Sample two

 #include <stdio.h>
int main()
{
char ch1;
char ch2;
scanf("%c", &ch1);
printf("ch1 = %d", ch1);
fflush(stdin);
scanf("%c", &ch2);
printf("ch2 = %d", ch2);
return ;
}
 

上面的实例只适用于Windows系统,在Linux环境下上面两种写法都是不起作用的,所以还要换个函数。

Sample three

 #include <stdio.h>
int main()
{
char ch1;
char ch2;
scanf("%c",&ch1);
printf("ch1=%d",ch1);
setbuf(stdin,NULL); 
scanf("%c",&ch2);
printf("ch2=%d",ch2);
return ;
}

(资料来源:http://www.ludou.org/c-clear-buffer-area.html

 
 
参考:http://www.ludou.org/c-clear-buffer-area.html

关于c语言char类型输入输出的一个bug的更多相关文章

  1. char类型能否存储一个中文字符?为什么

    char类型能否存储一个中文字符?为什么 解答:可以.一个char是两个字节,而一个中文也是两个字节.

  2. c语言 char*类型作为中间变量将许多字符串保存到一个数组的问题

    char*是一个字符串指针,如下面的程序value_作为一个中间变量用来在for循环中scanf输入的值的接收者,然后将value_保存到array中,但是一下程序会出现一个问题就是当你跳出这个函数时 ...

  3. char类型可不可以存储一个汉字

    java采用unicode,2个字节(16位)来表示一个字符, 无论是汉字还是数字字母,或其他语言.char 在java中是2个字节.所以可以存储中文 Java八种基本数据类型1)四种整数类型(byt ...

  4. K&R《C语言》书中的一个Bug

    最近在重温K&R的C语言圣经,第二章中的练习题2-2引起了我的注意. 原题是: Write a loop equivalent to the for loop above without us ...

  5. 关于各种类型数据char、int、double、float 所占空间长度的计算,而char类型让我长姿势了

    #include <iostream> int main() { using namespace std; //int A=10; //double B=6; cout << ...

  6. int类型和char类型的区别

    下面三个定义式的区别: int i = 1; char i = 1; char i = '1'; int用来定义整型变量,char用来定义字符型变量,要清楚的知道三个定义式的区别,可以比较它们在内存中 ...

  7. C语言基础(6)-char类型

    1. char常量.变量 使用单引号‘’引起来的就是char的常量 ‘a’是一个char类型的常量 “a”是一个字符串类型的常量 1是一个int型的常量 ‘1’是一个char型的常量 char a; ...

  8. C语言基础学习基本数据类型-Char类型

    char类型 char类型用于储存字母和标点之类的字符.但是在技术实现上char却是整数类型.为了处理字符,计算机使用一种数字编码,用特定的整数表示特定的字符.字符变量输入输出用%c符号.定义语法如下 ...

  9. 如何用一个语句判断一个整数是不是二的整数次幂——从一道简单的面试题浅谈C语言的类型提升(type promotion)

    最近招聘季,看JULY大哥的面试100题时,碰到这么一个扩展问题: 如何用一个语句判断一个整数是不是二的整数次幂?(此题在编程之美也有) easy, 2的整数次幂的二进制形式只有一个1,只要用i和i- ...

随机推荐

  1. php大力力 [031节] php设计系统后台菜单和样式设计

    php大力力 [031节] php设计系统后台菜单和样式设计 耗掉我一整夜的时间,把后台html设计了一个,对于我这样的html白痴,实属不容易啊. 留下一点点网上查找的网页知识: 索马里论坛群发简介 ...

  2. javaweb-c3p0

    //c3p0-config.xml <?xml version="1.0" encoding="UTF-8"?><c3p0-config> ...

  3. 爬虫再探实战(四)———爬取动态加载页面——请求json

    还是上次的那个网站,就是它.现在尝试用另一种办法——直接请求json文件,来获取要抓取的信息. 第一步,检查元素,看图如下: 过滤出JS文件,并找出包含要抓取信息的js文件,之后就是构造request ...

  4. 将byte[]数组数据转换为图片用于预览显示

    假如服务器返回给你的图片信息是byte[] 然后你需要将起转换成图片显示到你的view中去: 按以下的步骤 1.将获取的byte数组保存 假如为temp[]; 2.将temp[]转化为bitmap,你 ...

  5. linux命令:touch

    1:命令介绍: touch用来创建文件或修改文件和目录的时间戳,包括存取时间和更改时间. 2:命令格式: touch [选项] 文件 3:命令参数: -a   或--time=atime或--time ...

  6. vim-airline的theme

    仓库位置: https://github.com/vim-airline/vim-airline-themes 这些内置的这些主题,可以直接使用,方法是在.vimrc中写 let g:airline_ ...

  7. VS2010单元测试

    编号:1016时间:2016年5月26日09:35:27功能:VS2010单元测试URL :http://blog.csdn.net/tjvictor/article/details/6175362

  8. ucsc工具集合

    wget http://hgdownload.cse.ucsc.edu/admin/jksrc.zip 解压后所有工具在kent目录里 发现个更方便的.... http://hgdownload.cs ...

  9. box2dweb 学习笔记--sample讲解

    前言: 之前博文"台球游戏的核心算法和AI(1)" 中, 提到过想用HTML5+Box2d来编写实现一个台球游戏. 以此来对比感慨一下游戏物理引擎的巨大威力. 做为H5+box2d ...

  10. 关于SSH整合中对于Hibernate的Session关闭的问题

    在web.xml的Struts2的配置上面加上 <filter> <filter-name>OpenSessionInViewFilter</filter-name> ...