IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 《深入 C 语言和程序运行原理》11 标准库:深入理解标准 IO(学习笔记) -> 正文阅读

[C++知识库]《深入 C 语言和程序运行原理》11 标准库:深入理解标准 IO(学习笔记)

仅作为本人学习《深入 C 语言和程序运行原理》的学习笔记,原课程链接:极客时间《深入 C 语言和程序运行原理》——于航

输入输出(I/O)是应用程序不可或缺的一种基本能力。C 语言采用库函数的方式来实现 IO 功能(stdio.h),通过 IO 库函数,我们可以快捷地读取用户键盘输入、输出内容到控制台,乃至读写文件等一系列常规的 IO 功能。

快捷回顾 IO 接口的使用方法

下面是于航老师给出的一个简单的操作文件 IO 的例子:


#include <stdio.h>
int main(void) {
  printf("Enter some characters:\n");
  FILE* fp = fopen("./temp.txt", "w+");
  if (fp) {
    char ch;
    while (scanf("%c", &ch)) {
      if (ch == 'z') break;
      putc(ch, fp);
    }
  } else {
    perror("File open failed.");
  }
  fclose(fp);
  return 0;
}

运行时,在终端输入一串字符串,以 z 作为结束符,输入的字符串就会被写入到对应的文件中,

在这里插入图片描述

IO 接口的不同级别

IO 接口可以被分成不同层次,C 语言提供的 IO 接口属于“标准 IO”的范畴。与之相对的叫做“低级 IO”,低级 IO 操作的是更加底层的 IO,它会使用与具体操作系统相关的一系列底层接口来提供相应的 IO 能力。

使用“低级 IO”来重写上面的例子:


#include <unistd.h>
#include <fcntl.h>
int main(void) {
  const char str[] = "Enter some characters:\n";
  write(STDOUT_FILENO, str, sizeof(str));
  const int fd = open("./temp.txt", O_RDWR | O_CREAT);
  if (fd > 0) {
    char ch;
    while (read(STDIN_FILENO, &ch, 1)) {
      if (ch == 'z') break;
      write(fd, &ch, sizeof(ch));    
    }
  } else {
    const char errMsg[] = "File open failed.";
    write(STDERR_FILENO, errMsg, sizeof(errMsg));
  }
  close(fd);
  return 0;
}

运行效果是相同的

在这里插入图片描述

可以看出,“低级 IO”操作时参数更多,需要指定设备文件等,而标准 IO 屏蔽了底层不同系统的实现细节,所以标准 IO 可以做到“一次编写,到处编译”,即跨平台。

带缓冲的标准 IO 模型

虽然不同级别的 IO 接口实现的功能相同,但程序运行时背后的逻辑却有着较大的差异。

与低级 IO 相比,标准 IO 会为我们提供带缓冲的输入与输出操作,这些操作如何实现还因平台差异而不同。而低级 IO 接口会直接通过系统调用来完成响应的 IO 操作。

系统调用的过程涉及到进程在用户模式与内核模式之间的转换,其成本较高。标准 IO 接口通过添加缓冲区的方式,可以减少低级 IO 接口的调用次数。

以上面的代码为例,如果用低级 IO 接口,每次调用 write() 函数,都会将数据写入到文件中,

在这里插入图片描述
如果使用标准 IO 接口,每次调用 putc() 函数,并不会直接将数据写入到文件,而是写到了缓冲区。

在这里插入图片描述

危险的 gets 函数

C 语言提供的标准 IO 接口并非都是完备的。自 C90 开始,一个名为 gets 的 IO 函数被添加进标准库。该函数主要用于从标准输入流中读取一系列字符,并将它们放到由函数实参指定的字符数组中。

gets 函数在其内部实现中,并没有对用户的输入内容进行边界检查。因此,当用户实际输入的字符数量超过数组所成承受的最大容量时,超出的内容会直接覆盖掉栈帧中位于高地址处的其他数据。而当别有用心的攻击者精心设计输入内容时,甚至可以在某些情况下直接篡改当前函数帧的返回地址,并将其指向另外事先准备好的攻击代码。

正因为如此,gets 函数已经在 C99 标准汇总被弃用,并在 C11 及以后的标准中移除。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:17:37  更:2022-04-22 18:21:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:55:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码