第十五章:输入 / 输出函数
Github
链接:ch15. 输入 / 输出函数
IO
操作在工作中、项目中是相当常用的。文件的读取和写入都离不开这些函数,然而在平时简单的日常练习中是被经常忽略的点。还是得多练练的,简单知道函数原型,在使用的时候再查找相关文档进行细致的学习即可。
本章总结及注意点
部分课后习题解答
15.20 问题
-
首先,
fopen()
的函数原型为:FILE *fopen(char const *name, char const *mode);
若fopen
打开失败,则返回一个NULL
指针,其传递给后续的IO
函数时则不能达到预期,函数执行失败,但是程序是否失败这个得看编译器。如果程序不终止,则会操作内存中一块不可预料的位置的内容! -
我记得
FILE
就是个结构体,在此未被初始化,则程序失败,也可能修改一块不可预料的内存中的内容。 -
fclose()
函数调用失败一般是产生了一个bug
,需要发现并修复。如果大量的fclose()
函数均调用失败,则资源无法及时释放,则不能创建过多的流,无法再打开过多的文件。 -
没怎么想过这个问题,待我深入
Linux
内核去瞅瞅哈哈。 -
书中提及过:
NUL
字节总是留有空间,因此如果缓冲区大小为 1,那么就没有空间容纳任何char
来自流的角色。如果缓冲区大小为 2,则逐个读取字符。扫描二维码关注公众号,回复: 12866654 查看本文章 -
没太想清楚第一个值为啥最多是 6 个字符…答案:第一个值最多 6 个字符,第二个最多 1 个字符,第三个最多 4 个字符。算上两个空格和结束的
NUL
字节,缓冲区必须至少有 14 个字节长。 -
没有办法知道缓冲区必须有多大,除非提前能知道字符串的最长长度限制,如果在此语句之前没有检查
a
的长度,缓冲区可能会溢出不管它有多大。 -
好问题,浮点数本来就有经度丢失的现象,如果再多轮进行浮点数计算,那么结果将失真。在此如果 3.14159 打印的代码是
%.3f
。结果是 3.142。 -
没这样做过,见答案学习一下:编写一个程序在
errno
中存储所有可能的整数值,然后调用perror
。必须注意输出,因为对于不是合法错误代码的值可能会产生垃圾。 -
涉及到函数传参问题。因为它们要改变流的状态,
C
值传递只是一份拷贝,并不会实际改变流的状态。 -
r+
模式就可以了。w
模式截断文件,a
模式限制写入文件的末尾。 -
它允许一个特定的流重新打开到一个新的文件。例如,一个程序如果使用
printf
开始写入另一个文件,程序将不得不重新打开stdout
。这个函数是实现这一目标的可靠方法。 -
不值得。只有当一个项目有极高的速度、空间限制的时候,即其不够快或不够小的时候才去想想这些事情。
-
150087600。浮点数存取规则,以及采用
%d
来取字节翻译为整数。结果取决于制度,但它不会是3! -
字符串将左对齐。至少打印 6 个字符,但不超过 10 个。
-
常见坑点问题了。若实际值为 1.4049,那么前者肯定就是 1.405 了。后者自然就是 1.40。只会查看截断位置的下一个是否可以尽心四舍五入。
15.21 编程练习
-
getchar()
和putchar()
的使用即可。见demo02.c
。 -
长度限制已经给出,若是
gets()
,则缓冲区大小为 81,因为要存储一个NUL
字节。若为fgets()
则需要 82 大小,因为其还要存储一个换行符。见demo03.c
。 -
常见问题。使用
fgets()
来确保缓冲区不会被更长的输入行溢出。见demo04.c
。 -
进一步拓展。答案给的代码很清晰!非常值得学习,将打开文件操作封装为一个函数,参数为文件名和打开模式。真的诗一样的代码!见
demo05.c
。 -
利用
fgets()
读取一行进入缓冲区,再利用sscanf()
从缓冲区读取一个数字进入局部变量中,拿返回值判断其是否类型匹配为一个整数,若类型不匹配则输入停止。关于sscanf()
函数也是蛮重要的,可见P308
、P310-P312
。见demo06.c
。 -
是一个经典问题了,可以参考我的博文:[E模拟] lc9. 回文数(模拟+字符串+边界判断)
。给出了三种方法,其中最后一种折半的思想及效率都是非常出色的!在此使用sprintf()
函数挺不错的,将数字转到字符数组中进行存储,整数的话直接就是位数,而浮点数,如果格式化字符串没有规定小数位数,例如double
类型,采用%f
来进行格式化,那么会保留 6 位小数。不小心的话非常容易引起数组越界的错误!见demo07.c、demo08.c
。 -
答案:最多 10 个成员的限制使得使用
fgets
和sscanf
。假设每个年龄最多为三位数字(加上一个分隔空格),则缓冲区为 40 个字符就足够了。但是,问题说明并没有说被恰好一个空白字符分隔,所以这个解决方案使用一个 512 字符的缓冲区acters
代替。如果你知道一些关于输入的性质(例如,它是用一个编辑器的最大行大小是 512 字节),那么这种方法就很好。否则,这是有风险的而且你应该动态地分配一个可以扩展的缓冲区,每当发现一行太长了。见demo09.c
。 -
答案:虽然在问题陈述中没有明确指定,但一个重要的考虑事项是该做什么当转储文件的长度不为16字节的偶数倍时。一个简单的方法是简单地将丢失的字节报告为零。下面的解决方案构造了每一个将行放入内存中的缓冲区;这使得只打印部分中出现的数据变得更容易最后一行,仍然保持正确的格式。该程序将更容易修改时有人出现并想要改变格式(这是不可避免的)已经定义的名称用于与格式相关的数字,而不是文字常量。见
demo10.c
。 -
这几道题都不怎么想写了,初步学习它的思想即可。
-
见
demo11.c
。 -
建议去参考英文答案,很详细,很多,多到直接跳过的那种…
随笔
重点是重点,得多做做实验,玩一玩文件的操作。几个函数也需要知道它是干啥的就行了。
疑问
-
编程练习 9、10、11 简直就离谱了…本身也比较困,日后再补补看吧,不过大概率是不会补了。
-
本章内容蛮枯燥的,加上中间有些事情需要处理,断断续续整了有一周才整理完毕,就很慢…再看下一本书的
IO
相关内容的时候会拿出来对比着学习和复习一遍!