字符串:输入与缓冲区问题
<输入小结>
- 函数 回显 缓冲区 头文件
- getchar() 是 有 stdio.h
- getche() 是 无 conio.h
- getch() 否 无 conio.h
- scanf() 是 有 stdio.h
- gets() 是 有 stdio.h
- scanf() 是通用的输入函数。它可以读取多种类型的数据。
- gets() 是专用的字符串输入函数,与 scanf() 相比,gets() 的主要优势是可以读取含有空格的字符串。
<输入单个字符>
1.scanf()
示例:
char str;
scanf("%c",&str);
2.getchar()
示例:
char c=getchar();
printf("c:%c\n", c);
3.getche()
示例:
char c=getche();
printf("c: %c\n", c);
解释:输入@后,getche() 立即读取完毕,接着继续执行 printf() 将字符输出,所以没有按下回车键程序就运行结束了。
注意:getche() 位于 conio.h 头文件中。而这个头文件是 Windows 特有的,Linux 和 Mac OS 下没有包含该头文件。但可以系统定义一个函数实现getche()功能。
4.getch()
补充:所谓回显,就是在控制台上显示出用户输入的字符;没有回显,就不会显示用户输入的字符,就好像根本没有输入一样。
回显在大部分情况下是有必要的,它能够与用户及时交互,让用户清楚地看到自己输入的内容。但在某些特殊情况下,我们却不希望有回显,例如输入密码,有回显是非常危险的,容易被偷窥
示例
char c=getch();
printf("c:%c\n", c);
解释:输入@后,getch() 会立即读取完毕,接着继续执行 printf() 将字符输出。但是由于 getch() 没有回显,看不到输入的@字符,所以控制台上最终显示的内容为c: @。
注意:和 getche() 一样,getch() 也位于 conio.h 头文件中。这个头文件是 Windows 特有的,Linux 和 Mac OS 下没有包含该头文件。但可以系统定义一个函数实现getche()功能。
<输入一个字符串>
1.scanf()
scanf函数在给字符数组赋值时,当从键盘输入字符串后,系统会自动在最后添加结束标志‘\0’。
注意:如果输入的字符串中带空格,比如字符串“i like red”。就会出现一个问题。
示例
char str[20];
printf("请输入字符串:");
scanf("%s", str);
printf("输出结果:%s\n", str);
解释:系统将空格作为输入字符串之间的分隔符。也就是说,只要一“敲”空格,系统就认为当前的字符串已经结束,所以只会将空格之前的字符串存储到定义好的字符数组中。
解决办法1:
以空格为分隔符,计算有多少个字符串,有多少个字符串就定义多少个字符数组。比如“i like red”有两个空格,表示有三个字符串,那么就定义三个字符数组。
解决方法2:
使用gets函数
2.gets()
功能:从键盘将带空格的字符序列(以回车键结束)全部输入指定的字符数组,并自动加字符串结束符‘\0’。该函数可以将带空格的字符串全部输入字符数组中。
char str[20];
printf("请输入字符串:");
gets(str);
printf("输出结果:%s\n", str);
<缓冲区>
- 一、什么是缓冲区
缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。
缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。 - 二、为什么要引入缓冲区
缓冲区能使得低速的输入输出设备和高速的CPU能够协调工作 。
缓冲区主要作用是在于减少实际的I/O操作次数,即将多次操作尽量合并成一次的成批操作。举个例子:我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU还可以处理别的事情。
补充:在程序的执行过程,首先从硬盘执行程序,存放到内存,再给CPU运算与执行。由于硬盘的速度要比内存慢得多,而内存的速度又比CPU慢得多。因为CPU速度比其它硬件都要快,如果每次程序只传输一点数据,就需要传送很多次,这样会浪费很多时间。
注意:缓冲区与缓存并不相同 - 三、缓冲区的类型
缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。
1.全缓冲
在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。
2.行缓冲
在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。
3.不带缓冲
也就是不进行缓冲,标准出错情况stderr(标准错误)是典型代表,这使得出错信息可以直接尽快地显示出来。 - 四、缓冲区的刷新
下列情况会引发缓冲区的刷新:
(1).缓冲区满时;
(2).执行fflush语句;
(3).执行endl语句;(C++)
(4).关闭文件。
可见,缓冲区满或关闭文件时都会刷新缓冲区,进行真正的I/O操作。另外,我们可以使用fflush函数来刷新缓冲区(执行I/O操作并清空缓冲区) - 五.键盘操作演示行缓冲
getchar()函数的拓展介绍
函数原型:int getchar(void);(返回值为用户输入的ASCII码)
说明:getchar()函数的执行就是采用了行缓冲。当程序调用getchar()函数时,程序就等着用户按键,用户输入的字符被存放在键盘缓冲区中,直到用户按回车为止,回车字符也放在缓冲区中。当用户输入回车之后,getchar()函数才开始从键盘缓冲区中每次读入一个字符。也就是说,后续的getchar()函数调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完后,才重新等待用户按键。
<输入多个字符串>
示例:
char a[20];
char str[20];
printf("请输入文件名:");
scanf("%s",a);
printf("请输入关键字:");
//getchar();
//fflush(stdin);gets(str);printf("%s\n",str);
可以看到没等第二次的关键字的输入程序就运行结束了,为什么呢?
解释:当我们输入字符串file后按回车的时候就会把file连同换行符送入缓冲区,然而scanf只会接收字符串file,并把这个字符串送入到以a为首地址的地址空间中,同时在字符串后面自动加上一个‘\0’,那么如今缓冲区内就只有一个换行符了。当执行到gets()函数的时候,因为缓冲区内非空,无法输入字符串。gets直接会读取缓冲区中的换行符复制到str为首地址的内存空间,同时在字符串后面自动加上一个‘\0’,所以输出的str的结果是一个换行。
解决法1:当我们取消程序中注释语句getchar()的时候,getchar()会接收缓冲区中的第一个字符,那么缓冲区便空了。当执行到gets()的时候,由于缓冲区为空,那么程序便会停在gets()位置处的等待输入。
解决法2:也可以使用fflush(stdin)来刷新缓冲区,同样可以起到消除换行符的效果。因为fflush(stdin)的作用是清除标准输入缓冲区中的内容。
fflush()
函数原型:int fflush(FILE *stream)
fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准]。stdin表示标准键盘输入
fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
注意:某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能。在这些支持fflush(stdin)的编译器中,当输入多个字符串时,特别是一行代码输入一个字符串时,必须在每个输入前加上fflush(stdin)。
字符串:输入与缓冲区问题相关推荐
- c语言基础练习题 字符串输入scanf/gets 字符串赋值、比大小
PTA上C语言程序设计练习题,包含查找书籍.字符串排序.主要用到字符串输入scanf/gets 字符串赋值.比大小等知识. 1.查找书籍 习题9-4 查找书籍 (20 分) 给定n本书的名称和定价,本 ...
- 系统功能调用DOS中断INT 21H功能包单字符输入01单字符输出02字符串输入0a字符串输出09
微机原理与接口技术39讲 BIOS和DOS系统调用 BIOS更加底层,可以直接使用DOS DOS软中断INT 21H 调用步骤 单字符输入 按下回车退出 assume cs:codecode segm ...
- c语言输入任意长度字符串,读取不定长字符串输入
C语言通常使用scanf处理输入,如果要读取字符串,那么就需要定义一个字符数组(char[]).可是,如果数组定义长度不足,就可能发生溢出. 在C语言里有个可以用来读取字符的函数(getchar),我 ...
- 字符串输入的2种常用方法详解
字符串输入的2种常用方法详解 一.scanf函数 1.扫描集 2.逆向使用扫描集 二.gets函数 一.scanf函数 int main() {char arr[50] = { 0 };scanf(& ...
- 汇编实现字符串输入并倒序输出
汇编中的倒序输出 1.INT 21H的1号功能进行字符输入. 存放在数据段,倒序输出. DATAS SEGMENTMAXL DB 30 ;定义字符串大小做计数RLEN DB ? ;保存实际长度STR1 ...
- C语言的字符串输入gets()函数
C语言的字符串输入gets()函数 字符串简介 字符串(character string)是一个或多个字符的序列.如下所示: "Zing went the strings of my hea ...
- C语言中的字符串输入输出函数
1. 字符串输入(gets.fgets.gets_s.scanf) a. 分配内存空间a. 静态内存分配○ 指的是在编译时确定数组等数据类型的大小,然后由计算机分配好○ 在声明数组时要显式的声明数组的 ...
- C++语言篇 字符数组与字符串输入
一.在字符数组输入中,常用到cin , scanf() , gets() , cin.getline()和cin.get()函数. 注意:gets() , cin.getline()和cin.get( ...
- C语言带空格的字符串输入——gets()函数、scanf()函数缺陷以及改进后的gets_s()函数、scanf_s()函数的简单用法(上)
**在C语言中,带空格的字符串输入问题相对而言还是比较"坑"的,所以呢,小编就决定要专门谈一谈这个问题,希望对于初学者能够有所帮助. 该篇主要简述了C语言中gets()函数以及sc ...
- C语言字符串输入输出函数
C语言字符串输入输出函数 putchar()函数 getchar()函数 puts()函数 gets()函数 getche()函数 getch()函数 putchar()函数 格式: putchar( ...
最新文章
- 不要轻易挑战用户的习惯,否则会被用户打脸!
- 针对苹果最新审核要求 为应用兼容IPv6
- JDBC——入门知识【转】
- C++:搭建深度学习环境及实战
- oracle 找不到程序单元,Oracle Web ADI 加载时错误:ORA-06508: PL/SQL: 无法在调用之前找到程序单元...
- 在AngularJS的controller外部直接获取$scope
- Aptana 添加jQuery提示
- Activity intent经常使用的 FLAG 集合
- K-Means算法的Java实现
- JSP购物车案例精简版-适合小白学习
- Jetson 系列——nvidia jetson nano设置声卡
- 【一分钟了解UWP】微信UWP
- 在Virtualbox虚拟机中安装MSDOS(简易教程)
- 在PS中,1PX等于多少毫米?
- hdu 1880 魔咒词典 (字符串哈希)
- 在线购物系统分析类图
- 腾讯与阿里巴巴投资可编程芯片公司Barefoot Networks
- 什么是RESTful风格的API设计?
- 微信小程序,大佬救我!!!
- 渗透测试之Windows基础(新手必看)