第十五章:输入 / 输出函数
Github 链接:ch15. 输入 / 输出函数
IO 操作在工作中、项目中是相当常用的。文件的读取和写入都离不开这些函数,然而在平时简单的日常练习中是被经常忽略的点。还是得多练练的,简单知道函数原型,在使用的时候再查找相关文档进行细致的学习即可。
本章总结及注意点
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-svP2QmpH-1609746502962)(https://raw.githubusercontent.com/Y-puyu/picture/main/images/20210104102214.png)]](https://i-blog.csdnimg.cn/blog_migrate/89e7f6aad0961eb3a78c5cd397aa278d.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qOw8JaFy-1609746502965)(https://raw.githubusercontent.com/Y-puyu/picture/main/images/20210104103148.png)]](https://i-blog.csdnimg.cn/blog_migrate/9f48c9801be7f6d3536c37b7e2d0fecb.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZLRmUAJa-1609746502966)(https://raw.githubusercontent.com/Y-puyu/picture/main/images/20210104104007.png)]](https://i-blog.csdnimg.cn/blog_migrate/f23d6ce91cd9a169b2f6eae074b39f92.png)
部分课后习题解答
15.20 问题
-
首先,
fopen()的函数原型为:FILE *fopen(char const *name, char const *mode);若fopen打开失败,则返回一个NULL指针,其传递给后续的IO函数时则不能达到预期,函数执行失败,但是程序是否失败这个得看编译器。如果程序不终止,则会操作内存中一块不可预料的位置的内容! -
我记得
FILE就是个结构体,在此未被初始化,则程序失败,也可能修改一块不可预料的内存中的内容。 -
fclose()函数调用失败一般是产生了一个bug,需要发现并修复。如果大量的fclose()函数均调用失败,则资源无法及时释放,则不能创建过多的流,无法再打开过多的文件。 -
没怎么想过这个问题,待我深入
Linux内核去瞅瞅哈哈。![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OkqYvcPD-1609746502967)(https://raw.githubusercontent.com/Y-puyu/picture/main/images/20210104105805.png)]](https://i-blog.csdnimg.cn/blog_migrate/f11cedb082d82f45142b83442efcee13.png)
-
书中提及过:
NUL字节总是留有空间,因此如果缓冲区大小为 1,那么就没有空间容纳任何char来自流的角色。如果缓冲区大小为 2,则逐个读取字符。 -
没太想清楚第一个值为啥最多是 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。 -
这几道题都不怎么想写了,初步学习它的思想即可。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Em2EapPT-1609746502968)(https://raw.githubusercontent.com/Y-puyu/picture/main/images/20210104151812.png)]。](https://i-blog.csdnimg.cn/blog_migrate/8a1c92fafc9de4e5480e452b65cf859e.png)
-
见
demo11.c。 -
建议去参考英文答案,很详细,很多,多到直接跳过的那种…
随笔
重点是重点,得多做做实验,玩一玩文件的操作。几个函数也需要知道它是干啥的就行了。
疑问
-
编程练习 9、10、11 简直就离谱了…本身也比较困,日后再补补看吧,不过大概率是不会补了。
-
本章内容蛮枯燥的,加上中间有些事情需要处理,断断续续整了有一周才整理完毕,就很慢…再看下一本书的
IO相关内容的时候会拿出来对比着学习和复习一遍!
该博客围绕《C和指针》第十五章输入/输出函数展开。强调这些函数在工作项目中常用但日常练习易忽略。记录了本章总结、注意点,对部分课后习题进行解答,包括函数调用失败问题、缓冲区大小问题等,还提及编程练习思路及个人学习感悟。
1889

被折叠的 条评论
为什么被折叠?



