当前位置: 首页 > news >正文

C语言从头学44——I/O 函数(一)

        I/O函数就是负责与外部设备通信的函数。所谓外部设备,一般指键盘、显示器等负责输入输出的设备。这里的输入、输出都是相对于计算机内存而言的。严格地说,输入输出函数并不是直接与外部设备打交道,而是通过缓存进行中转通信。
一、缓存
       以文件读写为例,文件一般都保存在硬盘中。计算机读写硬盘的速度比我们人类读写速度快很多,但和CPU的速度相比,读写硬盘就像是慢动作。所以,程序不会直接读写硬盘。在C语言中,只要打开一个文件,就在内存里面为这个文件设置一个缓存区。程序向文件写入数据时,程序先把数据放入缓存,等到缓存写满了,再把里面的数据一次性写入磁盘文件,然后清空缓存再写入,周而复始;程序从文件读取数据时,也是先把一部分文件数据放到缓存,然后程序从缓存获取数据,等到缓存读空了,再把新的数据放入缓存,也是周而复始。内存的读写速度比磁盘读写速度快很多,缓存的作用就是通过增加每次读写硬盘的量从而减少读写磁盘的次数,提高程序效率。
       通过缓冲区间接读写的模式,对于程序来说,不是一次性读取或写入所有数据,而是持续不断类似流水的过程;缓存与硬盘间是批发,缓存与cpu间是零售,缓存相当于是中间商批发零售持续不断,这个过程称为字节流操作。
       C语言的输入输出函数:输入函数负责从文件获取数据;输出函数负责向文件写入数据。显示器、键盘、鼠标、打印机等外部设备都可以想象成是一个文件,计算机与它们之间的交互过程和与文件之间的交互过程完全一样。
二、下面开始介绍I/O函数
 (一)、printf()函数
   这个函数前面已经介绍过,不再介绍,只是强调printf属于I/O函数,它负责输出到屏幕。
 (二)、scanf()函数
   1、执行到scanf函数,程序会停下来等待用户从键盘输入数据;该函数定义在头文件 stdio.h。
        功能:scanf函数用于读取用户的键盘输入。
        使用格式:scanf(参1,参2); 
                参1 占位符格式字符串(告诉计算机后续输入值的类型) 
                参2 接收变量地址
        返回值:scanf读取成功返回接收变量个数;没有读取到数据或者匹配失败返回0;如果读取到的是"\0"或"\n"等,则返回-1。
       说明:
         a.由于scanf函数操作的是指针,所以参2不能直接写接收变量,需要对接收变量取址;
         b.如输入的数据是字符串,接收字符串的变量本就是指针,所以接收字符串的变量名前不能再取址;
         c.参1、参2既可以各自由一个占位字符串或单个变量地址组成,也可以由多个占位符字符串或多个变量地址组成,变量地址中间用","隔开。占位符与变量地址组形式、数量上都要匹配。实际使用时,输入的数据之间用与占位字符串之间相同的符号隔开,也可以每输入一个数据就打一次回车。但输入字符串还是建议调用一次scanf只输入一个字符串,或者干脆处理其它输入也是输入一个数据就调用一次scanf,既简单又不易出错。
       d.在使用scanf函数时,经常报警该函数不够安全,建议使用改进的scanf_s,这种情况处理办法有二:一是听人劝改用scanf_s函数,scanf_s使用方法与scanf基本一样,只有输入字符串时(占位符%s)需要增加第三个参数字符串长度;二是在程序头部加上语句" #define _CRT_SECURE_NO_WARNINGS",不让它报警;如此虽不报警,但也需注意接收字符串数组长度与输入字符串最大长度的匹配,不要造成溢出。
       e. scanf读取是顺序读取,比如读取int型数据,你输入了小数点,则读取到小数点就停了;小数点会赋给其它的变量,如果没有变量接收可能还会报错,所以使用scanf输入数据要做到准确无误,最好配合上输入提示。
   2、与scanf函数相关的占位符
        %c: 字符。
        %d: 整数。
        %f: float 类型浮点数。
        %lf: double 类型浮点数。
        %Lf: long double 类型浮点数。
        %s: 字符串。
      说明:
       a.上面所有占位符之中,除了%c以外,都会自动忽略开头的空格;%c可以接受空格。如果希望%c也不接收空格,则需这样写scanf(" %c",&x),即在%前加上一个空格。
       b.%s从当前第一个非空白字符开始读起,遇到空白字符(即空格、换行符、制表符等)停止。因此scanf不适合读取包含空格的字符串。按照字符串的定义, scanf处理%s时,都会在字符串末尾加一个"\0"结束符。
       c.为防止输入字符串时造成溢出,可变通一下%s,写成%ns形式,n就是允许输入的最大长度,这样输入多了的部分会舍弃,不会造成溢出。
   3、赋值忽略符
     比如,输入日期有人习惯写成2024-8-7,也有人习惯写成2024/8/7,实际计算机需要的是2024、6、18 这三个数,三者之间的连接可以忽略。这种情况就用到了忽略符,"%*c"就表示可以忽略掉一个输入的字符,无需有对应的变量接收,把c换成d也可,但一般情况下忽略的多是字符。
   4、关于scanf函数使用举一个小例子:

#define _CRT_SECURE_NO_WARNINGS //禁止对scanf函数报警
#include<stdio.h>
int main(void)
{
//调用scanf函数输入并显示整型、浮点两个数据int a=0;float x=0;printf("请输入整型数 a 浮点数 x 两数中间用--隔开\n");int ret=scanf("%d--%f", &a,&x); //输入格式举例:15--3.14159回车if (ret == 0){printf("输入错误,结束程序!");return 0;}printf("你输入数据a=%d  x=%f\n",a,x); //运行结果:你输入数据a=15  x=3.141590
//调用scanf函数输入并显示一个字符串char str[128];printf("请输入一个字符串(最长127字节)\n");scanf("%127s", str); //str结尾需有\0,故最多只能输入127个字符//比如输入:天津市南开区printf("你输入的字符串是:%s\n", str); //运行结果:你输入的字符串是:天津市南开区
//调用scanf函数使用输入不同格式的日期并显示int year, month, day;printf("请输入日期\n");scanf("%d%*c%d%*c%d", &year, &month, &day); //无论输入2024-8-7、2024/8/7均可正常输入printf("%d年%d月%d日\n", year, month, day); //运行结果:2024年8月7日fflush(stdin);getchar();getchar();return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 软件测试生命周期、BUG描述与处理策略
  • leetcode面试算法题
  • Java程序员接单分享
  • Redis远程字典服务器(1)—— 初识Redis
  • SSH协议管理多主机(SSH协议的两种用法、生产环境用户初始化、结果返回值处理)
  • 人工智能算法工程师(高级)课程11-自然语言处理之NLP的语言模型-seq2seq模型,seq+注意力与代码详解
  • 【数据结构】链表篇
  • 深入解析:Amazon Bedrock 上 Claude 3 Haiku 的微调测试报告
  • 基于STM32的智能宠物喂食器
  • MySQL的索引事务和JDBC编程
  • QT(2.0)
  • Datawhale AI 夏令营(2024第三期)AI+逻辑推理方向 模型微调学习笔记
  • MySQL——数据表的基本操作(四)删除数据表
  • 避免死锁的资源分配算法——银行家算法
  • C语言——扫雷游戏
  • 2019.2.20 c++ 知识梳理
  • Gradle 5.0 正式版发布
  • JS专题之继承
  • leetcode-27. Remove Element
  • mysql中InnoDB引擎中页的概念
  • Service Worker
  • SQLServer之创建数据库快照
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 判断客户端类型,Android,iOS,PC
  • 如何用vue打造一个移动端音乐播放器
  • 设计模式 开闭原则
  • 微服务核心架构梳理
  • 用jQuery怎么做到前后端分离
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ​马来语翻译中文去哪比较好?
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • ‌JavaScript 数据类型转换
  • ## 1.3.Git命令
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • #if #elif #endif
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (java)关于Thread的挂起和恢复
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (计算机网络)物理层
  • (实战篇)如何缓存数据
  • (四)Android布局类型(线性布局LinearLayout)
  • (四)软件性能测试
  • (转)程序员技术练级攻略
  • .gitignore文件忽略的内容不生效问题解决
  • .net 8 发布了,试下微软最近强推的MAUI
  • .Net CF下精确的计时器
  • .net core Swagger 过滤部分Api
  • .net core 连接数据库,通过数据库生成Modell
  • .NET Core 中插件式开发实现
  • ::