单字符 I/O:getchar() 和 putchar()

getchar() 和 putchar() 每次只处理一个字符

getchar() 和 putchar() 都不是真正的函数,它们被定义为供预处理器使用的宏

getchar() 不带任何参数,它从输入队列中返回下一个字符

例如,下面的语句读取下一个字符输入,并把该字符的值赋给变量 ch

ch = getchar();
等同于
scanf("%c", &ch);

putchar() 打印它的参数

例如,下面的语句把之前赋给 ch 的值作为字符打印出来

putchar(ch);
等同于
printf("%c", ch);

getchar() 和 putchar() 不需要转换说明,因为它们只处理字符

缓冲区

回显用户输入的字符后立即重复打印该字符是属于无缓冲(或直接)输入,即正在等待的程序可立即使用输入的字符

大部分系统在用户按下 Enter 键之前不会重复打印刚输入的字符,这种输入形式属于缓冲输入。用户输入的字符被收集并储存在一个被称为缓冲区(buffer)的临时存储区,按下 Enter 键后,程序才能使用用户输入的字符

缓冲分为两类:完全缓冲 I/O 和行缓冲 I/O

完全缓冲输入指的是当缓冲区被填满时才刷新缓冲区(内容被发送到目的地),通常出现在文件输入中

缓冲区的大小取决于系统,常见的大小是 512 字节和 4096 字节

行缓冲 I/O 指的是在出现换行符时刷新缓冲区

键盘输入通常是行缓冲输入,所以在按下 Enter 键后才刷新缓冲区

结束键盘输入

文件、流和键盘输入

文件和存储器中储存信息的区域

通常,文件都保存在某种永久存储器中(如,硬盘、U 盘或 DVD 等)

从较低层面上,C 可以使用主机操作系统的基本文件工具直接处理文件,这些直接调用操作系统的函数被称为底层 I/O(low-level I/O)

由于计算机系统各不相同,所以不可能为普通的底层 I/O 函数创建标准库

从较高层面上,C 还可以通过标准 I/O 包(standard I/O package)来处理文件

不同的系统储存文件的方式不同

有些系统把文件的内容储存在一处,而文件相关的信息储存在另一处,有些系统在文件中创建一份文件描述

在处理文件方面,有些系统使用单个换行符标记行末尾,而其他系统可能使用回车符和换行符的组合来表示行末尾

有些系统用最小字节来衡量文件的大小,有些系统则以字节块的大小来衡量

如果使用标准 I/O 包,就不用考虑这些差异。即使系统实际用的是回车符和换行符的组合来标记行末尾,I/O 函数会在两种表示法之间相互转换

C 程序处理的是流而不是直接处理文件

流(stream)是一个实际输入或输出映射的理想化数据流,这意味着不同属性和不同种类的输入,由属性更统一的流来表示

打开文件的过程就是把流和文件相关联,而且读写都通过流来完成

C 把输入和输出设备视为存储设备上的普通文件,尤其是把键盘和显示设备视为每个 C 程序自动打开的文件

stdin 流表示键盘输入,stdout 流表示屏幕输出

getchar()、putchar()、printf()、scanf() 函数都是标准 I/O 包的成员,处理上面这两个流

文件结尾

检测文件结尾的一种方法是,在文件末尾放一个特殊的字符标记文件结尾,如 Ctrl + Z

操作系统使用的另一种方法是储存文件大小的信息,如果文件有 3000 字节,程序在读到 3000 字节时便达到文件的末尾

在 C 语言中,用 getchar() 读取文件检测到文件结尾时将返回一个特殊的值,即 EOF(end of file 的缩写)

scanf() 函数检测到文件结尾时也返回 EOF

通常,EOF 定义在 stdio.h 文件中:

#define EOF (-1)

因为 getchar() 函数的返回值通常都介于 0~127,这些值对应标准字符集。但是,如果系统能识别扩展字符集,该函数的返回值可能在 0~255 之间。无论哪种情况,-1 都不对应任何字符,所以,该值可用于标记文件结尾

某些系统也许把 EOF 定义为 -1 以外的值,但是定义的值一定与输入字符所产生的返回值不同

如果包含 stdio.h 文件,并使用 EOF 符号,就不必担心 EOF 值不同的问题

EOF 是一个值,标志着检测到文件结尾,并不是在文件中找得到的符号

绝大部分系统都有办法通过键盘模拟文件结尾条件

// 重复输入,直到文件末尾
#include <stdio.h> int main(void)
{
int ch; while ((ch = getchar()) != EOF)
putchar(ch); return 0;
}

由于 getchar() 函数的返回类型是 int,如果把 getchar() 的返回值赋给 char 类型的变量,一些编译器会警告可能丢失数据

使用该程序进行键盘输入,要设法输入 EOF 字符。不能只输入字符 EOF,也不能只输入 -1(输入 -1 会传送两个字符:一个是连字符和一个数字 1)

正确的方法是,必须找出当前系统的要求,即规定的文件结尾信号

重定向和文件

在默认情况下,C 程序使用标准 I/O 包查找标准输入作为输入源

程序可以通过两种方式使用文件:

第一种方法是,显示使用特定的函数打开文件、关闭文件、读取文件、写入文件,诸如此类

第二种方法是,设计能与键盘和屏幕互动的程序,通过不同的渠道重定向输入至文件和从文件输出

重定向的一个主要问题是它与操作系统有关,与 C 无关

UNIX、Linux 和 DOS 重定向

UNIX(运行命令行模式时)、Linux(ditto)和 Windows 命令行提示(模仿旧式 DOS 命令行环境)都能重定向输入、输出

重定向输入让程序使用文件而不是键盘来输入,重定向输出让程序输出至文件而不是屏幕

1.重定向输入

// 重复输入,直到文件末尾
#include <stdio.h> int main(void)
{
int ch; while ((ch = getchar()) != EOF)
putchar(ch); return 0;
}

该程序获取用户从键盘输入的输入,如果要处理一个名为 words 的文本文件的话

sch01ar@ubuntu:~$ ./echo_eof < words

运行结果

< 符号是 UNIX 和 DOS/Windows 的重定向运算符

该运算符使 words 文件与 stdin 流相关联,把文件中的内容导入 echo_eof 程序

echo_eof 程序本身并不知道(或不关心)输入的内容是来自文件还是键盘,它只知道这是需要导入的字符流,所以它读取这些内容并把字符逐个打印在屏幕上,直到读到文件结尾

因为 C 把文件和 I/O 设备放在一个层面,所以文件就是现在的 I/O 设备

2.重定向输出

// 重复输入,直到文件末尾
#include <stdio.h> int main(void)
{
int ch; while ((ch = getchar()) != EOF)
putchar(ch); return 0;
}

如果要用该程序把键盘输入的内容发送到名为 mywords 的文件中

sch01ar@ubuntu:~$ ./echo_eof > mywords

运行结果

> 符号也是 UNIX 和 DOS/Windows 的重定向运算符

它创建了一个名为 mywords 的新文件,然后把 echo_eof 的输出(即,你输入字符的副本)重定向至该文件中

重定向把 stdout 从显示设备(即,显示器)赋给 mywords 文件

如果已经有一个名为 mywords 的文件,通常会擦除该文件的内容,然后替换新的内容

在 UNIX 中,按 Ctrl + D 结束程序

在 DOS 中,按 Ctrl + Z 结束程序

在每行的末尾按 Enter 键,才能把缓冲区的内容发送给程序

C Primer Plus学习笔记(七)- 字符输入/输出和输入验证的更多相关文章

  1. [C语言学习笔记三]格式化输出和输入

    使用 printf 函数来输出,使用 scanf 函数来输入 在 printf 函数中使用变量,需要使用占位符代替. int 型一般存储整数,使用 %d 代替 long long int 型一般存储长 ...

  2. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  3. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  4. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  5. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

  7. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  8. iOS 学习笔记七 【博爱手把手教你使用2016年gitHub Mac客户端】

    iOS 学习笔记七 [博爱手把手教你使用gitHub客户端] 第一步:首先下载git客户端 链接:https://desktop.github.com 第二步:fork 大神的代码[这里以我的代码为例 ...

  9. Linux学习笔记(七) 查询系统

    1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...

随机推荐

  1. Elasticsearch6.0简介入门介绍

    Elasticsearch简单介绍 Elasticsearch (ES)是一个基于Lucene构建的开源.分布式.RESTful 接口全文搜索引擎.Elasticsearch 还是一个分布式文档数据库 ...

  2. svn working copy locked的解决方法

    在使用svn更新或提交代码时,会报"svn working copy XXX locked"的错误,利用svn客户端工具TortoiseSVN的cleanup也不能解决问题. 我们 ...

  3. whois老域名挖掘技术

    我一般通过站长工具域名WHOIS查询定向收集一些特定域名,拿来分析网站存活站点. 例如: 查询域名基本信息 WHOIS反查得到大部分域名注册信息 一般大一点的厂商都有几百个域名,我们通过此处收集大量顶 ...

  4. 最全面的linux信号量解析

    信号量 一.什么是信号量 信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程) 所拥有. 信号量的值为正的时候,说明它空闲.所测试的线程可以锁定而使用它.若为0,说明 它被占用, ...

  5. Python — 多线程与多进程

    1.多线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位,一个进程可以包含多个线程.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线 ...

  6. android中shape的属性

    <shape> <!– 实心 –> <solid android:color=”#ff9d77″/> <!– 渐变 –> <gradient an ...

  7. MySQL 创建千万集数据

    - MySQL测试任务:使用存储过程,往表中插入千万级数据,根据索引优化速度 -- 1.使用索引查询 -- 2.不使用索引查 -- 3.比较两者查询速度的差异 1.创建数据和索引 1.创建索引测试表 ...

  8. 深入探索C++对象模型 读书笔记

    第1章 关于对象 1.C++在布局以及存取时间上的主要的额外负担是由virtual引起的,包括: a.virtual function机制,引入vptr以及vtbl,支持一个有效率的"执行期 ...

  9. visual assist(VA)设置快捷键(其它安装的插件设置快捷键也在这里)

    安装完visual assist后发现快捷键无法使用纠结,然后找如何去设置快捷建以此记录一下: 在Tools-->customize-->Keyboard-->Add-ins 常用的 ...

  10. tag问题