题目

输入一个整数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. 【LeetCode OJ】Triangle

    Problem Link: http://oj.leetcode.com/problems/triangle/ Let R[][] be a 2D array where R[i][j] (j < ...

  2. URAL 2040 (回文自动机)

    Problem Palindromes and Super Abilities 2 (URAL2040) 题目大意 给一个字符串,从左到右依次添加,询问每添加一个字符,新增加的回文串数量. 解题分析 ...

  3. lhgdialog 与后台交互的对话框

    官网:http://www.lhgdialog.com/ 1. 调用打开dialog的按钮 <span class="txtdec fs10 open"> <a ...

  4. MySQL优化—工欲善其事,必先利其器之EXPLAIN(转)

    最近慢慢接触MySQL,了解如何优化它也迫在眉睫了,话说工欲善其事,必先利其器.最近我就打算了解下几个优化MySQL中经常用到的工具.今天就简单介绍下EXPLAIN. 内容导航 id select_t ...

  5. Netty ChannelOption 解释

    Name Associated setter method "writeBufferHighWaterMark" 默认 64 * 1024(用法未知) "writeBuf ...

  6. 递归---n皇后

    ---恢复内容开始--- #include "stdafx.h" #include <iostream> #include <fstream> //文件流 ...

  7. Iptables 规则 一些简单实例和详细介绍

    设定规则 iptables -p INPUT DROP iptables -p OUTPUT ACCEPT iptables -p FORWARD DROP 1.防止外网用内网IP欺骗 iptable ...

  8. 二叉搜索树(Binary Search Tree)

    二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树. 二叉搜索树:一棵二叉树,可以为空:如果不为空,满足以下性质: 非空左子树的所有键值小于其根结点的键值: 非空右 ...

  9. ubuntu 下建立桌面快捷方式

    1)新建文件eclipse.desktop,命令如下: sudo vim /usr/share/applications/eclipse.desktop 2)在新建文件中添加如下内容并保存: [Des ...

  10. 五 浅谈CPU 并行编程和 GPU 并行编程的区别

    前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺 ...