题目

输入一个整数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. 监听Android CTS测试项解决方案(一)

    前言: 首先这里需要详细叙述一下标题中"监听Android CTS测试项解决方案"的需求.这里的需求是指我们需要精确的监听到当前CTS测试正在测试的测试项. 因为我们知道CTS认证 ...

  2. linux常用命令:2权限管理命令

    权限管理命令 1.权限管理命令:chmod 命令名:chmod 命令英文原意:change the permissions mode of a file 命令所在路径:/bin/chmod 执行权限: ...

  3. iOS:音频

    ios中有很多支持音频的控件,如:播放本地音乐(file URL)的AVAudioPlayer和AudioToolbox.Framework.可以播放音乐库音乐的MPMusicPlayerContro ...

  4. XMLParser解析xml--内容源自网络(在静态库中不能用GDATA来解析,因为静态库不能加动态库)

    </Books> 从其文档结构我们可以看出,要定义一个Book实体类描述具体的书籍信息,其中用于存储的相关xml文档元素的实例变量与对应元素同名(本例:title.author.summa ...

  5. 第一个Shader的更新,增加爆光度, 属性改为数值型(更直观,精确)

    Shader "Castle/ColorMix" { Properties { // 基本贴图 _MainTex ("Texture Image", 2D) = ...

  6. 在Runbook中添加Checkpoint-workflow

    本文说明的是使用Checkpoint-workflow的一种场景(当然还有其他场景需要Checkpoint-workflow). 起因:Windows Azure对Automation账户中的Runb ...

  7. UDP 打洞 原理解释

    终于找到了一份满意的UDP打洞原理解释,附上正文,自己整理了一下源码 3.3. UDP hole punching UDP打洞技术 The third technique, and the one o ...

  8. jquery 下了框

    //选中特定值 $("#Select_GBType").attr("value", "选中项ID"); //获取选中项的值 $(" ...

  9. ZMMR103-数据批量导入

    ************************************************************************ Title : ZMMR103 ** Applicat ...

  10. Codeforces Round #368 (Div. 2)A B C 水 图 数学

    A. Brain's Photos time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...