• C Primer Plus(6) 中文版 第8章 字符输入/输出和输入验证 8.3 结束键盘输入


    8.3 结束键盘输入
    C的确提供了一个在文本中用不到的字符来标记输入完成。
    8.3.1 文件、流和键盘输入
    文件(file)是存储器中存储信息的区域。通常,文件都保存在某种永久存储器中。毫无疑问,文件对于计算机系统相当重要。
    C是一门强大、灵活的语言,有许多用于打开、读取、写入和关闭文件的库函数。从较低层面上,C可以使用主机操作系统的基本文件工具直接处理文件,这些直接调用操作系统的函数被称为底层I/O(low-level I/O)。由于计算机系统各不相同,所以不可能为普通的底层I/O函数创建标准库,ANSI C也不打算这样做。然而从较高层面上,C还可以通过标准I/O包(standard I/O package)来处理文件。
    这涉及创建用于处理文件的标准模型和一套标准I/O函数。在这一层面上,具体的C实现负责处理不同系统的差异,以便用户使用统一的界面。
    差异指的是不同的系统存储文件的方式不同。有些系统把文件的内容存储在一处,而文件相关的信息存储在另一处;有些系统在文件中创建一份文件描述。在处理文件方面,有些系统使用单个换行符标记末尾,而其他系统可能使用回车符和换行符的组合来标记行末尾。
    有些系统用最小字节来衡量文件的大小,有些系统则以字节块的大小来衡量。
    如果使用标准I/O包,就不用考虑这些差异。因此,可以用if( ch == '\n' )检查换行符。即使系统实际用的是回车符和换行符的组合来标记末尾,I/O函数会在两种表示法之间相互转换。
    从概念上看,C程序处理的是流而不是直接处理文件,流(stream)是一个实际输入或输出映射的理想化数据流。这意味着不同属性和不同种类的输入,由属性更统一的流来表示。于是,打开文件的过程就是把流与文件相关联,而且读写都通过流来完成。
    本章着重理解C把输入和输出设备视为存储设备上的普通文件,尤其是把键盘和显示设备视为每个C程序自动打开的文件。stdin流表示键盘输入,stdout流表示屏幕输出。getchar()、putchar()、printf()和scanf()函数都是标准I/O包的成员,处理这两个流。
    可以从处理文件的方式来处理键盘输入。C的输入函数内置了文件结尾检测器。既然可以把键盘输入视为文件,那么也应该能使用文件结尾检测器结束键盘输入。
    8.3.2 文件结尾
    计算机操作系统要以某种方式判断文件的开始和结束。检测文件结尾的一种方法是,在文件末尾放一个特殊的字符标记文件结尾。不过现在有一些其他的选择,例如记录文件的大小。所以现代的文件文件不一定有嵌入的Ctrl+Z,但是如果有,该操作系统会将其视为一个文件结尾标记。
    操作系统使用的另一种方式是存储文件大小的信息。
    无论操作系统实际使用何种方式检测文件结尾,在C语言中,用getchar()读取文件结尾时将返回一个特殊的值,即EOF(end of file的缩写)。scanf()函数检查到文件结尾时也返回EOF。通常,EOF定义在stdio.h文件中:
    #define EOF (-1)
    定义为-1是因为getchar()函数的返回值通常都介于0~127,这些值对应标准字符集。但是,如果系统能识别扩展字符集,该函数的返回值可能在0~255。无论哪种情况,-1都不对应任何字符,所以,该值可用于标记文件结尾。
    某些系统也许把EOF定义为-1之外的值,但是定义的值一定与输入字符所产生的返回值不同。如果包含stdio.h文件,并使用EOF符号,就不用担心EOF值不同的问题。这里关键要理解EOF是一个值,标志着检测到文件结尾,并不是在文件中找得到的符号。
    绝大部分系统(不是全部)都有办法通过键盘模拟文件结尾条件。
    /* echo_eof.c -- repeats input to end of file */
    #include
    int main(void)
    {
        int ch;
        
        while ((ch = getchar()) != EOF)
            putchar(ch);
        
        return 0;

    /* 输出:

    */ 

    注意以下几点。
    *不用定义EOF,因为stdio.h中已经定义过了。
    *不用担心EOF实际值,因为EOF在stdio.h中用#define预处理指令定义,可直接使用,不必再编写代码假定EOF为某值。
    *变量ch的类型从char变为int,因为char类型的变量只能表示0~255的无符号整数,但是EOF的值是-1。还好,getchar()函数实际返回值的类型是int,所以它可以读取EOF字符。如果实现使用有符号的char类型,也可以把ch声明为char类型,但最好还是用更通用的形式。
    *由于getchar()函数的返回类型是int,如果把getchar()的返回值赋给char类型的变量,一些编译器会警告可能丢失数据。
    *ch是整型不会影响putchar(),该函数仍然会打印等价的字符。
    *使用该程序进行键盘输入,要设法输入EOF字符。正确的方法是,必须找出当前系统的要求。
    在大多数Linux和UNIX系统中,在一行开始处按下Ctrl+D会传输结尾信号。许多微型计算机系统都把一行开始处的Ctrl+Z识别为文件结尾信号,一些系统把任意位置的Ctrl+Z解释为文件结尾信号。
    每次按下Enter键,系统便会处理缓冲区存储的字符,并在下一行打印该输入行的副本。
    UNIX风格模拟文件结尾(Ctrl+D)。在PC中,按下Ctrl+Z。 
    注意 模拟EOF和图形界面
    模拟EOF的概念是在使用文本界面的命令行环境中产生的。在这种环境中,用户通过击键与程序交互,由操作系统生成EOF信号。但是在一些实际应用中,却不能很好地转换成图形界面,这些用户界面包含更复杂的鼠标移动和按钮点击。程序要模拟EOF的行为依赖于编译器和项目类型。

  • 相关阅读:
    【MicroPython ESP32】 esp模块功能函数详解和使用示例
    linux创建mysql新用户及授权
    C#在Excel与Word中写入上角标与下角标
    zeromq-01-初学
    ros2与Python入门教程-创建发布和订阅
    简单记录关于Velocity的一些想法
    PostgreSQL设置中文语言界面和局域网访问
    九、池化层
    Birdboot第六天 jar包 数据库
    国产电影机跟国外品牌相比如何?导演评“差距不大”博冠8K全画幅摄像机落地长春电影制片厂虚拟影棚开拍
  • 原文地址:https://blog.csdn.net/weixin_40186813/article/details/126216523