C语言缓冲区问题——getchar描述

缓冲区的概念

  在计算机运行过程中,CPU负责对数据的加工和处理,而硬件设备则负责对数据的传输、表示或存储,如打印、输入\输出等。在这一过程中,不同设备的处理速度有较大差别,从而造成一定程度的效率问题。如在打印机输出过程中,若CPU直接将计算结果交由打印机输出,由于打印输出速度较慢,CPU将需要等待上一个结果输出完成后才能继续输出下一个结果。同样,在输入过程中,CPU需要一直等待直到设备I\O将读取的数据交由其处理。在这个过程中,由于CPU速度较I\O设备快,CPU在大部分时间处于等待状态,从而使得CPU利用率很低,造成系统昂贵资源的浪费。

  为了解决CPU与外围硬件设备速度不匹配的问题,提高CPU的利用率,提高系统的并行效率,在系统中引入了缓冲区(buffer)的概念。

  缓冲区是在物理内存中独立分配的用于数据移动过程中临时存储数据的内存区域。(Wiki Data Buffer)

  在使用Buffer之后,数据的传输过程中,可以将数据先放置在缓冲区中,再交由其他设备处理。以上面操作过程为例,CPU可以先将计算结果存放在缓冲区中,再由打印机从其中读取数据,在打印机输出的过程中,CPU可以处理其他数据而无需等待。在输入过程中,CPU不等待输入完成,I\O设备将用户输入存放在缓冲区中,再去请求CPU资源,CPU则可直接从缓冲区中读取数据进行处理,从而大大提高了CPU的利用率和运行效率。

标准I\O的缓冲

  标准I\O根据不同的应用需求,提供了全缓冲、行缓冲、无缓冲三种缓冲方式。

  全缓冲:只有当划定的缓冲区被填满或者数据读取至末尾时,才开始执行I\O操作(执行系统提供的read\write操作)。磁盘文件的读写一般采用这种方式。

  行缓冲:当输入输出过程遇到换行符‘‘\n"或者当分配缓冲区已满时,才开始执行I\O操作。一般涉及终端的读写操作如stdio与stdout使用这种缓冲方式。

  无缓冲:当有数据产生时,马上由相应的设备进行处理。一般来说stderr(standard error)使用这种缓冲方式,使得有错误信息时马上能够得到响应。需要注意的是,标准库不缓存并不意味着操作系统或者设备驱动不缓存

  注意,以上关于stdio/stdout的缓冲方式并不是直接规定死的。一些语言的语言规范会对缓冲实现给出一定的限制,但并不具体,只是许多标准I/O是以上述方式实现的而已。可以参考关于流和缓冲区

  

I\O函数——getchar

  getchar()是用于字符输入的C库函数,其函数的声明包含在头文件stdio.h,函数定义 int getchar(void).

  getchar()的功能是读取标准输入stdin中的一个字符。getchar从标准输入中读取数据,而stdin是采用行缓冲的方式记录用户输入,也就是只有当用户键入回车键或输入至缓冲区末尾时,才会开始I\O操作,亦即读取一个字符。这样用户可以一次输入不止一个字符,读取过后缓冲区可能不为空。当再次调用getchar()时,若缓冲区不为空,getchar()就会直接读取在缓冲区中字符,而不是等待用户输入。可以认为是getchar()等待的是行缓冲的完成,而不是用户输入的完成,在行缓冲完成后,只要缓冲区不为空,getchar()就可以读取字符,而不需要等待用户输入

  

/*codeblocks13.12*/
#include <stdio.h>

int main(void)
{
    char ch = ‘\0‘;

    while(ch != ‘\n‘)
    {
    printf("输入一个字符:");
    ch = getchar();
    printf("\n");
    putchar(ch);
    printf("\n");
    }

    return 0;
}

  程序的运行结果如下:

  

  可以明显看到,后续执行中并不要求用户输入,getchar()会直接读取缓冲区中的数据。而且对于字符的读取操作而言,换行符‘\n‘也被视为一个字符,而不是单纯的结束标志。

等待用户输入的字符输入

  getchar()可以直接从缓冲区中读取字符,而不等待用户输入,但这种方式也有可能带来潜在的错误。这里给出两种等待用户输入的字符传入方式。

  1.使用getche()与getch()函数。都从键盘上读入一个字节,其中后者不将字符回显到屏幕上。以这两个函数读取字符时,都是通过调用函数读取一个键盘输入且只有一个。如调用getche(),键盘敲击‘abc‘时,只有一个字符‘a‘会被读取。其他字符为无效输入。

  2.在每次getchar()之后,手动对缓冲区进行清除操作。可以使用fflush()函数清理缓冲区。C标准规定 fflush()函数可用来刷新输出(stdout)缓冲区(一般是将缓冲区数据写回存储设备)。但对于标准输入(stdin)则没有明确定义。部分编译器定义了 fflush( stdin )的实现,如微软的VC。也就是不同的编译器对于 fflush( stdin )的支持可能不同。GCC编译器没有定义它的实现,所以不能使用 fflush( stdin )来刷新输入缓冲区。

时间: 2024-10-14 11:11:58

C语言缓冲区问题——getchar描述的相关文章

C语言缓冲区清空

C语言中有几个基本输入函数: //获取字符系列 int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void); //获取行系列 char *fgets(char * restrict s, int n, FILE * restrict stream); char *gets(char *s);//可能导致溢出,用fgets代替之. //格式化输入系列 int fscanf(FILE * restrict stream, co

关于C语言缓冲区的清理

一直对于输入输出流的问题没有弄明白 今天做OJ题,涉及到字符串的输入 这里有三种关于缓冲区清理的问题 法一: fflush(stdio); 按百度经验的说法,这种用法,只适用于VC6.0版本 法二 setbuf(stdio,NULL); 法二是将标准输入流设为空缓冲区 法三 char temp; //写法一 while( temp = getchar()!='\n'&&temp!=EOF ) //写法二 while(1) { temp = getchar(); if(temp=='\n'|

c语言:用getchar函数读入两个字符给c1,c2,用putchar和printf输出。思考问题

用getchar函数读入两个字符给c1,c2,分别用putchar和printf输出这两个字符.思考以下问题: (1)变量c1和c2定义为字符型还是整型?或二者皆可? (2)要求输出c1和c2的ASCII码,应如何处理? (3)整形变量和字符变量是否在任何情况下都可以互相代替?char c1, c2;和int  c1, c2;是否无条件等价? 程序: #include<stdio.h> int main() { char c1, c2; printf("请输入两个字符c1,c2:&q

C语言缓冲区(缓存)详解

缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区.缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区.      为什么要引入缓冲区比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度. 又比如,

基于C语言EOF与getchar()的使用详解

转自:http://www.jb51.net/article/36848.htm   大师级经典的著作,要字斟句酌的去读,去理解.以前在看K&R的The C Programming Language(SecondEdition) 第1.5节的字符输入/输出,被getchar()和EOF所迷惑了.可能主要还是由于没有搞清楚getchar()的工作原理和EOF的用法.因此,感觉很有必要总结一下,不然,很多琐碎的知识点长时间过后就会淡忘的,只有写下来才是最好的方法. 其实,getchar()最典型的程

c语言输入输出缓冲区的概念

语言输入输出缓冲区的概念 你肯定会奇怪为什么一开始先说这个,一开始不都是数据类型什么的嘛,这个写在最前面因为后面的程序即使最简单的code都会用到输入输出,输出比较简单,可以放在后面再说,但是输入就不同了,如果不先了解一下,可能会得到和你预想不同的结果哦^_^.也正是由于和一般的c语言介绍方式不同,为了看起来正规一些,我就把这章叫做chapter0了,完全可以先跳过去,直接看chapter1. 1.getchar 先引用一下前人的成果(有修改)^_^:http://blog.csdn.net/c

C语言#getchar()函数

1.getchar()的作用 getchar()函数的作用是从缓冲区读入一个字符的数据,第一次读取数据getchar()会等待用户键入ENTER然后开始从缓冲区进行读取数据,如果缓冲区的数据大于1个字节,剩下的数据会暂时存储在缓冲区,getchar会依次进行读取,而不需要用户再次输入ENTER来触发读取. getchar()的返回值是一个整型的数据,其值对应字符的ASCII码. 2.统计输入空格数量的小程序 1 #include<stdio.h> 2 3 main() { 4 5 int n;

C语言难点1之输入输出,链接,字符串操作

C语言难点1之输入输出,链接,字符串操作 最近发现写了一段时间的C之后,还是有一些点并没有很好的get,我就想总结出来,写个系列博客,自己也好好的整理一下思路.这个系列主要出自三本书:<C专家编程>,<C陷阱和缺陷>,<C和指针>.有兴趣的同学可以好好看一下这几本书,对于打好C语言的基础是个非常不错的几本书. 1 一些输入输出的格式 对应的printf():和scanf()函数:在这里我给出常用的scanf格式码,和printf()函数也是一样的. 2 getchar(

Linux C 字符函数 getchar()、putchar() 与 EOF 详解

首先给出<The_C_Programming_Language>这本书中的例子: #include <stdio.h> int main() { int c; c = getchar(); while (c != EOF) { putchar(); c = getchar(); } return 0; } 这里主要解释下为什么要用int型来接受getchar函数. 很多时候,我们会写这样的两行代码: char c; c = getchar(); 这样就很有可能出现问题.因为getc