11|标准库:深入理解标准 IO
该思维导图由 AI 生成,仅供参考
快速回顾 IO 接口的使用方法
- 深入了解
- 翻译
- 解释
- 总结
C 语言标准 IO 模型是应用程序中不可或缺的基本能力。文章深入介绍了标准 IO 模型及其背后的原理。首先回顾了标准库提供的 IO 接口的使用方法,然后对比了标准 IO 和低级 IO 接口的不同级别。标准 IO 提供了带缓冲的输入输出操作,通过缓冲区减少低级 IO 接口的调用次数,提升了性能。文章还提到了标准 IO 接口提供了自由使用不同缓冲策略的能力,可以通过接口如 fflush 和 setvbuf 来控制缓冲区的使用。总的来说,标准 IO 模型在接口设计与使用方式上更加统一和通用,能够屏蔽底层不同系统的实现细节,同时提供了性能优化的机制。 文章还介绍了低级 IO 的相关实现细节,包括系统调用的机制和使用方式。通过实际代码展示了在机器指令层面使用系统调用的过程,深入解释了系统调用函数的调用过程和参数传递方式。 此外,文章还警示了C语言标准IO接口中存在的安全隐患,特别是对于 gets 函数的使用。强调了 gets 函数的不安全性,并指出了主流编译器对其的弃用和相关安全技术的应用。 总的来说,本文通过深入解析C语言标准IO模型及其底层实现细节,以及对安全性的警示,为读者提供了全面的技术视角和实用建议。
《深入 C 语言和程序运行原理》,新⼈⾸单¥59
全部留言(12)
- 最新
- 精选
- liu_liusetvbuf(fp, buf, _IOFBF, 5); 设置了缓冲区的大小为 5。表示每输入 5 个字符,就会写入文件。_IOFBF 表示 fully buffer。 而未使用 setvbuf 时,经测试,默认缓冲区大小是 4kb,当在输入 4k 个字符后,才会写入文件。
作者回复: 正解!
2022-01-0512 - liu_liuungetc 用于向流里面放回字符,取出字符的顺序与放回字符的顺序相反。 比如放回的顺序如下: ungetc ('d', file); ungetc ('c', file); ungetc ('b', file); ungetc ('a', file); 那么取出时,依次是 a、b、c、d。 在网上查资料说,ungetc 不同平台实现可能不一样,有的说调用多次可能会失败,只保证一次的放回。 我在 unbuntu 64 位 下测试,多次调用是没问题的,貌似可放回的字符数是有个缓冲区大小的。 请老师解答下~
作者回复: 很棒!实践出真知!实际上,标准中对 ungetc 的规定是,一个大小为 1 字节的“回退 buffer”是可以被保证的,但是多于一次的连续回退操作能否成功,则完全取决于具体实现。通常来说在实践中,这个 buffer 的大小最小只有标准规定的 1 字节,最大甚至可以达到 4k 字节大小。
2022-01-0527 - ppd0705我记得 APUE 上说缓冲有三种类型:全缓冲、行缓冲、无缓冲。看来写入普通文件,标准 IO 默认是全缓冲,低级 IO 是行缓冲?
作者回复: 这个是不一定的,比如在标准 IO 里,标准错误输出肯定不是全缓冲的。相应的,对于低级 IO 来说,大多数方法都是无缓冲的,但具体使用之前还是最好看一下 man 文档,以防万一。
2022-03-143 - ZR2021讲的太好了,尤其是那个内嵌汇编,眼前一亮的感觉!!!不过老师,还是有几个问题想请教下您: 1. 系统调用传参使用的是寄存器,不管参数是值还是地址,传地址的话,底层会调用拷贝函数进行拷贝,那如果是结构体类型的值传参要怎么办,还是说不能有这种传参方式的? 2. 系统调用传参就那么几个寄存器传参,传参个数超过了怎么办呢?还是也被规定了不能超过6个参数的,貌似我确实也没见过超过6个参数的系统调用…… 3.这种汇编内嵌的方式感觉很厉害的样子,之前一直想学下就是学不好,后面有没有相应的课程讲解的,讲下常见的要点什么的…… 还有,这种内嵌汇编方式的代码效率比c/c++高的吗,如果高的话高在哪里呢?还是只是为了做一些高级语言做不到的事情? 期待老师的解惑,可能有些问题比较低级……
作者回复: 感谢认可,都是很好的问题!下面是回答: 1. 在 Linux x86-64 系统调用中,有一些是需要结构体对象作为参数的,比如 sys_readv。但传递方式都是通过指针,不会有直接按值传递结构体对象的情况。 2. 在 Linux x86-64 系统调用中,是没有需要通过栈来传参的系统调用的。 3. 我们在后面的课程中还会用到,但不会有专门的章节介绍哈。实际上对于大部分手写汇编,执行效率都是没有编译器产出的汇编高的,所以在日常的 C 编程中并不常用。并且由于内联汇编也会有兼容性问题,包括 asm 关键字的用法我印象里不同编译器的支持程度都是不同的。当然如果需要使用,主要关注具体汇编指令的用法,以及 asm 关键字的用法就可以。前者可以参考具体平台上的具体 manual,后者以 GCC 为例,可以参考:https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
2022-01-0833 - pedro老师,有没有啥 gets 的替代品?
作者回复: 可以使用 fgets 函数哈。
2022-01-0523 - may_huang> cat my_fopen.c #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; } seroiuts01390> gcc my_fopen.c # /workspace/git/ehuamay/test seroiuts01390> ./a.out Enter some characters: File open failed.: Permission denied Segmentation fault 为啥在我的环境里运行会coredump?
作者回复: 看起来是因为没有权限 “Permission denied”。SF 可能是因为文件没有被打开,却执行了 “fclose(fp);”。
2022-08-03归属地:北京1 - ppd0705老师,请问 "C 语言提供的 IO 接口属于“标准 IO”的范畴。" 这句话可以理解为 stdid 库提供的接口属于标准 IO 范畴吗?不然 fcntl 不也算 C 语言提供的一个标准库吗?
作者回复: 标准 IO 实际上是特指由 ISO C 标准定义的一系列接口,这些接口被定义在 C 标准中。这里你提到的 fcntl 只能算是 POSIX.1-2001 标准中的接口。
2022-03-1521 - Jack系统调用对应的 ID,去哪里找?
作者回复: Linux x86-64 可以在这边查哈:https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
2022-01-091 - Geek__38012c6589d3这节讲的真好 于老师牛逼
作者回复: 感谢认可!^~^
2022-02-08 - 墨老师,请问这一篇用到的内联汇编的语法,有没有什么文档可以查阅的
作者回复: 有的,可以参考这个文档:https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
2022-02-08