再学C语言27:输入和输出——缓冲区

news2025/1/11 17:06:24

I/O函数:输入/输出函数

I/O函数将信息传输至程序并从程序中传出信息,如printf()、scanf()、getchar()、putchar()等函数


getchar()和putchar()每次输入/输出一个字符

示例代码:

#include <stdio.h>
int main(void)
{
    char c;

    // 输入回显,遇到'.'字符时终止
    while((c = getchar()) != '.')
    {
        putchar(c);
    }
    return 0;
}

运行结果:


一、缓冲区

立即回显:非缓冲输入(直接输入)

延迟回显:缓冲输入,键入的字符被收集并存储在一个被称为缓冲区的临时存储区域中,按下回车可使所键入的字符快对程序变为可用

缓冲区的作用:

1)将若干个字符作为一个块传输比逐个发送这些字符耗费的时间更少

2)如果输入有误,缓冲区允许键盘更正功能以修正错误

一些交互性的程序需要非缓冲输入,缓冲和非缓冲输入具有各自的用途

缓冲分为两类:完全缓冲(fully buffered)I/O和行缓冲(line-buffered)I/O

完全缓冲输入:缓冲区满时被清空,内容被发送至其目的地;通常出现在文件输入中;缓冲区大小取决于系统,常见大小为512字节和4096字节

行缓冲输入:遇到一个换行字符时缓冲区被清空,内容被发送至其目的地;键盘输入是标准的行缓冲,按下回车键将清空缓冲区

ANSI C指定应该对输入进行缓冲;K&R则将选择权留给编译器的编写者

不存在调用非缓冲输入的标准ANSI方式;使用的方法取决于计算机系统

(上面的示例代码的运行结果体现的是缓冲输入,即输入的字符串在按下回车键之后才显示在屏幕上)

二、终止键盘输入

上面的示例代码中,通过字符'.'结束键盘输入,但是现实中字符'.'可能在正常输入中出现,这种通过特定字符结束键盘输入的方法在一些场合下会遇到不便

因此,一般希望终止字符不在文本中出现,不会在希望程序结束前打断程序

1. 文件、流和键盘输入

文件(file):一块存储信息的存储器区域

C处理文件的2种级别:

级别一(低级I/O):使用宿主操作系统的基本文件工具处理文件

级别二(标准I/O包):创建用于处理文件的I/O函数的标准模型和标准集;系统之间的差异由特定的C实现来处理,上层应用通过统一接口实现文件处理

概念上,C程序处理一个流而不是直接处理文件

流(stream)是一个理想化的数据流,实际输入或输出映射到这个数据流

具有不同属性的多种类型的输入由流表示,具有更多统一的属性

打开文件的过程成为将流与文件关联,并通过流进行读写的过程

C对待输入和输出设备与其对对待存储设备上的普通文件相同

键盘和显示设备作为每个C程序自动打开的文件来对待

键盘输入由一个被称为stdin的流表示;屏幕(或其他输出设备)上的输出由一个被称为stdout的流表示

getchar()、putchar()、printf()、scanf()函数都是标准I/O包的成员,同stdin和stdout两个流打交道

结论:可以使用与处理文件相同的技术来处理键盘输入;例如,读取文件的程序需要一种方法检测文件的结尾,以了解停止读取的位置

C输入函数装备有一个内置的文件尾检测器,对于键盘输入也可以使用文件尾检测器终止键盘输入

2. 文件结尾

计算机操作系统判断文件结尾的方法:

1)在文件中放置一个特殊字符来标志结尾(例如内嵌的Ctrl+Z字符)

2)让操作系统存储文件大小的信息

C的处理方法:让getchar()函数在到达文件结尾时返回一个特殊值,而不去管操作系统是如何检测文件结尾的;赋予该值的名称是EOF(end of file,文件尾)

检测到文件尾时getchar()和scanf()的返回值是EOF

通常EOF在stdio.h中定义:

#define EOF (-1)

将EOF定义为-1:在绝大多数情况下,值-1都不对应任何字符,所以可以用其表示文件结尾

一些系统也许会将EOF定义为-1以外的值,但该定义总是与合法的输入所产生的返回值不同

实际使用时,只要包含了stdio.h文件并使用了EOF符号,就不必考虑EOF的数值定义,EOF代表的值表示检测到文件结尾,其值并不是实际出现在文件中的一个符号

示例代码:改写一开始的程序

#include <stdio.h>
int main(void)
{
    int c;

    // 输入回显,遇到EOF时终止
    while((c = getchar()) != EOF)
    {
        putchar(c);
    }
    return 0;
}

1)stdio.h中对EOF进行定义

2)使用时不必在意EOF的值,不需要给EOF重新赋值,直接用符号表示

3)因为EOF可能用-1表示,所以变量c的类型改为int

4)键盘输入时,键入EOF的方式根据系统而异


在大多数Unix系统上,在一行的开始键入Ctrl+D会导致传送文件结尾信号

许多微机系统将一行的开始位置键入的Ctrl+Z识别为文件尾信号;还有一些微机系统把任意位置的Ctrl+Z解释为文件尾信号


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vivado综合设置之-resource_sharing

-​resource_sharing用于对算数运算&#xff08;加法、减法和乘法&#xff09;实现资源共享&#xff0c;以节约LUT资源&#xff0c;有3个值&#xff1a;auto、off和on&#xff0c;默认是auto。 默认情况下&#xff0c;将resource_sharing设置为auto即可。 本文验证-resource_…

[Leetcode] 将二叉搜索树变平衡

将二叉搜索树变平衡&#xff1a;https://leetcode.cn/problems/balance-a-binary-search-tree/给你一棵二叉搜索树&#xff0c;请你返回一棵 平衡后的二叉搜索树&#xff0c;新生成的树应该与原来的树有着相同的节点值。如果有多种构造方法&#xff0c;请你返回任意一种。如果一…

Codeforces Round #842 (Div. 2)-C. Elemental Decompress

题目&#xff1a; 题目大意&#xff1a; 给定一个数列t&#xff0c;你构造两个数列a和b&#xff0c;使得max(a[i],b[i])t[i] 核心思想&#xff1a; 1、先根据给出的数组进行放置&#xff0c;优先放到a数组中&#xff0c;如果这个数已经在a数组中出现了&#xff0c;再去放到b数…

sentinel的使用

一、sentinel控制台的使用1、sentinel控制台jar包地址&#xff1a;Releases alibaba/Sentinel GitHub账号密码都为sentinel控制台访问地址&#xff1a;http://localhost:80802、sentinel的maven坐标<dependency><groupId>com.alibaba.cloud</groupId><a…

Android基础入门教程——2.2 LinearLayout(线性布局)

总结图片2. weight权重白色占总数量的2份&#xff0c;绿色占总数的1份。<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.co…

树莓派最新版系统烧写和网络配置

树莓派笔记1.树莓派烧写篇2.树莓派WIFI配置篇3.树莓派ping外网4.树莓派git篇5.参考1.树莓派烧写篇 目前烧写最新版本32位系统(2022-09-22发布的)&#xff0c;默认移除了pi用户&#xff0c;没有用户就无法SSH登录(无屏幕)&#xff0c;建议使用raspberry pi imager烧写工具&…

通过USB转TTL串口下载stm32程序

文章目录前言一、硬件及其接线二、使用步骤1.主芯片STM32F103C8T6开发板2.转串口模块接线3.CH340驱动及安装方法4.CH340驱动及安装方法4.下载测试5.0.91寸OLED 接口演示例程前言 前期我们下载程序都是使用STlink进行下载的&#xff0c;现在给大家提供一种新的程序下载方法&…

5G小基站国产化超五成,美国芯片仅占1%,难怪美国芯片难卖了

日前日媒拆解中国某科技企业的5G小基站&#xff0c;发现它的中国零部件占比达到55%&#xff0c;而来自美国的零部件占比仅为1%&#xff0c;显示出这家企业在去美化取得了重大进展&#xff0c;如此也就能理解为何如今美国芯片难卖了。日媒指出该科技企业的5G小基站国产化零部件占…

动态规划 完全背包问题

目录 LintCode 炼码完全背包问题 【解法一】 【解法二】 完全背包问题 【解法一】 解释&#xff1a; 第一个for循环表示从第一个物品开始遍历 第二个for循环表示逆向 从背包容量为m时开始处理&#xff08;滚动数组&#xff09; 第三个for循环表示装入k个该物品&#xff0c;装…

【前端】Vue项目:旅游App-(9)city:固定tab栏、内容中显示数据

文章目录目标过程与代码Tab一直显示的两种方法方法1&#xff1a;fixed定位方法2&#xff1a;设置height和overflow-y&#xff08;效果不好&#xff09;content显示数据效果总代码city.vue相关参考目标 上一篇获取了服务器中的数据&#xff1a;【前端】Vue项目&#xff1a;旅游…

【数据结构】完全二叉树——啊堆堆堆

一、树概念及结构树的概念树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n > 0&#xff09;个有限节点组成的一个具有层次关系的集合。把它叫做树是因为他看起来像是一颗倒挂起来的树&#xff0c;也就是说它是根朝上&#xff0c;而叶子朝下的。-> 有一个特殊的…

Find My产品|Ember发布支持苹果Find My温控马克杯

在 CES2023 展会上&#xff0c;温控马克杯制造商 Ember 表示&#xff0c;计划在 2023 年 Q2 上市一款支持苹果 Find My 应用的全新 Travel Mug 2 马克杯。 这项新功能将使用户能够在 Find My 应用中追踪 Travel Mug 2 的位置&#xff0c;就像追踪iPhone、iPad、AirPods 或其他…

埃科光电在科创板IPO过会:拟募资11亿元,董宁为实际控制人

近日&#xff0c;上海证券交易所披露的信息显示&#xff0c;合肥埃科光电科技股份有限公司&#xff08;下称“埃科光电”获得科创板上市委会议通过。据贝多财经了解&#xff0c;埃科光电于2022年6月22日在科创板提交招股书&#xff0c;并于12月29日递交招股书&#xff08;上会稿…

图像分割笔记

图像分割笔记 目标&#xff1a; 实现图像中多个物体的分割&#xff0c;多个物体的标注方式为0,1,2,3,0表示背景&#xff0c;1表示一种物体&#xff0c;2表示另一种物体&#xff0c;假设我们现在的分割任务里面有5个目标需要&#xff0c;如肺叶分割&#xff0c;5个肺叶的标注方…

飞书开放平台-全新消息卡片搭建工具

前言你还在为需要手撕 JSON 代码而烦恼吗&#xff1f;消息卡片搭建工具全新升级&#xff0c;为你带来更优雅的卡片创作体验&#xff1a;&#x1f31f; 卡片编辑&#xff1a;纯可视化操作编辑消息卡片&#xff0c;再也不用碰代码&#x1f31f; 我的卡片&#xff1a;一键保存卡片…

Vue3 Composition API

文章目录p15 Vue3 Composition APIMixin全局混入options API的弊端认识Componsition APIsetup函数的参数setup不可以使用thisReactive APIrefreadonlyp16 Composition API(二)toRefscomputedwatchEffect在setup中使用refwatchp15 Vue3 Composition API Mixin 全局混入 、 opti…

使用正则表达式删除注释

以下摘自某网友来信&#xff1a; 难点 Javascript 不支持点号匹配换行符, 因此无法直接进行多行匹配处理前面没有 http: 的 //, 当然要用否定前瞻( negative lookbehine)了:(?<!http:)\/\/. 可惜 javascript 不支持 思路 关于多行匹配 这个问题, 之前我已经说过, 要点…

多线程初阶(四)定时器及线程池

目录 前言&#xff1a; 定时器 使用标准库中定时器 模拟实现定时器 线程池 使用标准库中的线程池 代码实现 ThreadPoolExecutor类介绍 构造方法参数介绍 拒绝策略介绍 模拟实现线程池 代码实现 提出问题 小结&#xff1a; 前言&#xff1a; 这篇文章同上一篇文章…

简单实现Java定时器

✨✨hello&#xff0c;愿意点进来的小伙伴们&#xff0c;你们好呐&#xff01; &#x1f43b;&#x1f43b;系列专栏&#xff1a;【JavaEE】 &#x1f432;&#x1f432;本篇内容&#xff1a;自己实现Java定时器 &#x1f42f;&#x1f42f;作者简介:一名现大二的三非编程小白&…

【手写 Vue2.x 源码】第九篇 - 对象数据变化的观测情况

一&#xff0c;前言 上篇&#xff0c;主要介绍了数组深层观测的实现&#xff0c;核心几个点如下&#xff1a; 最初仅对数组类型进行了原型方法重写&#xff0c;并未进行递归处理&#xff0c;所以&#xff0c;当时仅实现了数组的单层劫持&#xff1b; 通过对数组进行 observe…