这篇说一说C语言中字符输入输出的内容
内容在书8章.
1.单字符IO
我们经常引入的"stdio.h"中有这样两个处理单字符的函数"putchar()"和"getchar()".
一个一个字符的处理,效率好像很低.但是"这种方法很适合计算机,而且是绝大多数文本处理程序所使用的核心方法"(217页).
这个程序简单的测试了这两个函数,这个程序会原样输出用户输入的内容,直到用户输入'#',程序结束.
# include <stdio.h>
int main(void) {
char c;
while((c = getchar()) != '#') {
putchar(c);
}
return 0;
}
运行结果
123qwe
123qwe
!@$%^&*()_+
!@$%^&*()_+
qadeddgf#456
qadeddgf输入了#,程序结束.
可以看到前两行都正常的输出了,而到了第三行,我在中间输入了一个'#',发现在'#'的位置跳出循环,且'#'后的内容都没有被输出.
但是回忆一下之前使用的scanf(),它是在我们输入"回车"时就会结束输入,继续执行下面的代码.在这里却不行,只能使用自己设定的字符来结束输出.
2.缓冲区
2.1 什么是缓冲区?
就是对某种东西起暂时存储的作用,比如我们的胃就对我们吃下去的东西起暂存作用.
在老式的系统中,上面的程序运行之后可能是这样的:
112233qqwwee!!@@^^**
可以看到输入的字符立刻被显示出来,而之前的运行结果只有在回车之后才会显示,这就是缓冲区的作用了.
2.2 有什么作用?
首先我们的硬盘在读写文件时,单个的大文件速度是要比多个小文件快很多的,同理"将若干字符作为一个块传输比逐个发送这些字符节约时间"(218页).
再看看没有缓冲区的执行结果,可以看到假如输入了错误的字符也是直接被显示出来的,而在有缓冲区的运行结果中,可以在输入时检查自己的输入是否有问题并对出错的地方进行修改.
2.3 一定需要缓冲区吗
显然不是,比如我们在玩游戏的时候一般会用到wasd四个键控制方向,而且一般来说都是需要按下即响应.试想此时如果使用了缓冲区,按一下按键还要敲一下回车才能响应,这游戏也就没法玩了.
所以还是看情况,需要和不需要缓冲区的情况都是存在的.
3.结束键盘输入
有什么方法可以简单的结束键盘输入吗?
在我们引入的"stdio.h"中有一个"EOF"
#define EOF (-1)
意思是"end of file".之前使用的scanf()中检测到文件结尾时返回的就是EOF.
可以看到"EOF"的值是-1,为什么是-1?因为在使用getchar()的时候,返回值通常都在0~127之间,最多也就是0~255,不论什么时候,-1都不对应任意一个字符.所以可以使用-1来作为结尾标识.
那么如何输入一个"EOF"?这跟系统有关系."多数Unix和Linux中,在一行开始处按下Ctrl+D会传输文件结尾信号.许多系统把一行开始处的Ctrl+Z识别为文件结尾信号,而一些系统则把任意位置的Ctrl+Z识别为结尾信号."
下面来测试一下EOF
# include <stdio.h>
int main(void) {
char c;
while((c = getchar()) != EOF) { //直接使用即可
putchar(c);
}
printf("读取到EOF,程序结束.\n");
return 0;
}
运行结果1,Windows下输入Ctrl+Z
123
123
qwertyuio
qwertyuio
^Z
读取到EOF,程序结束.
运行结果2,Windows下输入Ctrl+D
123
123
adfergaf!!!###
adfergaf!!!###
^D
123dasavsgfsq
123dasavsgfsq
^Z
读取到EOF,程序结束.
每次回车都会把缓冲区中的内容输出.
可以看到Windows下是使用Ctrl+Z输入EOF.