apue第五章习题

本文详细解答了APUE第五章的多个习题,涉及缓冲区管理、printf返回值、标准I/O流的fsync函数使用、getchar错误及exit与_Exit的区别。讨论了在不同情况下 fgets和fputs的行为,以及标准输入输出的行缓冲特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

5.1 用setvbuf实现setbuf

void setbuf(FILE *stream, char *buf);
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
当buf为NULL,则为无缓冲,否则为全缓冲。

void my_setbuf(FILE *restrict fp, char *restrict buf)
{
    setvbuf(fp, buf, buf? _IOFBF: _IONBF, BUFSIZ);
}

5.2 图5-5中的程序利用每次一行I/O(fgets和fputs函数)复制文件。若将程序中的MAXLINE改为4,当复制的行超过该最大值时会出现什么情况。对此进行解释。

fgets函数读入数据,直到行结束或缓冲区满(当然会留出一个字节存放终止null字节)。同样fputs只负责将缓冲区的内容输出直到遇到null字节,而并不考虑缓冲区是否包含换行符。所以,如果MAXLINE设得很小,这两个函数仍正常工作,只不过缓冲区较大时,函数被执行的次数要多于MAXLINE值设置得较大的时候。

5.3 printf返回0值表示什么

没有输出字符,即printf(“”);

5.4 下面的代码在已写机器上运行正确,而在另一些机器运行时出错,解释问题所在。

#include    <stdio.h>

int
main(void)
{
    char    c;

    while ((c = getchar()) != EOF)
        putchar(c);
}

这是一个比较常见的错误。getc以及getchar的返回值是int 类型,而不是char类型。由于EOF经常定义为-1,那么如果系统使用的是有符号的字符类型,程序还可以正常工作。但如果使用的是无符号字符类型,那么返回的EOF被保存到字符c后将不再是-1,所以,程序会陷入死循环。

5.5 对标准I/O流如何使用fsync函数?

使用方法,先调用fflush后调用fsync(保证文件系统与缓冲区内容的一致性)。fsync所使用的参数由fileno函数获得。如果不调用fflush,所有的数据仍然在内存缓冲区中,此时调用fsync将没有任何效果。

示例代码:

#include "apue.h"

int fsync_streamaa(FILE *);
int main(void)
{
    FILE *fp;
    if ((fp = fopen("txt.txt", "w+")) == NULL)
    {
        perror("fopen error!");
        exit(-1);
    }
    fprintf(fp, "As I lay dying");
    fsync_streamaa(fp);
    _Exit(0);
}
int fsync_streamaa(FILE *fp)
{
    fflush(fp);
    return (fsync(fileno(fp)));
}

使用自定义的fsync_streamaa函数之后,可以在fopen的文件中看到写入的内容,而将fflush注释掉时,fopen的文件无内容。

PS:exit与_Exit区别:exit直接使进程停止运行,清除其使用的内存空间,并清除其在内核的各种数据结构;exit 函数则在这些基础上做了一些小动作,在执行退出之前还加了若干道工序。exit() 函数与 _Exit() 函数的最大区别在于exit()函数在调用exit 系统调用前要检查文件的打开情况,把文件缓冲区中的内容写回文件。也就是“清理I/O缓冲”

5.6 在图1-7和图1-10程序中,打印的提示信息没有包含换行符,程序也没有调用fflush函数,请解释输出提示信息的原因是什么?

标准输入和标准输出均为行缓冲方式,fgets每次调用stdin均会冲洗缓冲区。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值