APUE-第五章学习-标准I/O库-习题

本文探讨了C语言中如何通过setvbuf函数控制文件缓冲,解析了不同缓冲模式的应用场景,并讨论了fgets与fputs函数在文件复制过程中的行为表现及printf函数返回值的意义。

5.1 用setvbuf实现setbuf

#include "stdio.h"
#include "apue.h"

void my_setbuf(FILE *restrict fp,char *restrict buf){
    if(buf == NULL){
        if(setvbuf(fp,buf,_IONBF,BUFSIZ) != 0){
            err_quit("setvbuf error!");
        }
        printf("no buf\n");
    }else{
        if(fp == stderr){
            if(setvbuf(fp,buf,_IONBF,BUFSIZ) != 0){
                err_quit("setvbuf error");
            }
            printf("no buf\n");
        }else if(fp == stdin || fp == stdout){
            if(setvbuf(fp,buf,_IOLBF,BUFSIZ) != 0){
                err_quit("setvbuf error");
            }
            printf("line buf\n");
        }else{
            if(setvbuf(fp,buf,_IOFBF,BUFSIZ) != 0){
                err_quit("setvbuf error");
            }
            printf("fully buf\n");
        }
    }
    exit(0);
}

5.2 5.8 节中的程序利用fgets和fputs函数复制文件,每次I/O操作只复制一行,若将程序中的MAXLINE改为4,当复制的行超过该最大值时会发生什么情况?对此进行解释。

和原来的结果相同,fgets给定参数n,fgets只能读取n-1个字符(包括换行符),如果有一行超过n-1个字符,那么fgets返回一个不完整的行,也就是说,只读取该行的前n-1个字符,但是,缓冲区总是以null字符结尾,对fgets的下一次调用会继续读该行。

5.3 printf()返回0值意味着什么?

printf()函数的返回值,如果成功,则返回写入的字符总数,否则返回一个负数。也就是写入的字符数为0。

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

#include <stdlib.h>

int main(void){
    while((c = getchar()) != EOF)
        putchar(c);
}

因为getchar返回值为整型,而不是字符型。由于EOF经常被定义为-1。那么如果系统使用的是有符号的字符类型,程序可以正常工作,但是如果使用的是无符号字符类型,则程序会进入死循环。

5.5 为什么tempnam限制前缀为5个字符?

5个字符长的前缀、4个字符长的进程唯一标识再加上5个字符长的系统内唯一标识(进程ID)刚好组成14位的UNIX传统文件名长度限制。

<think>好的,我现在需要帮助用户查找APUE(Advanced Programming in the UNIX Environment)书中第五章关于标准I/O的知识小结。首先,我要回忆一下APUE这本书的结构,通常第五章确实涵盖了标准I/O的相关内容,比如文件操作、缓冲机制、流的概念等。用户提到他们需要这一章的小结,所以我需要整理出主要的知识点。 根据用户提供的引用内容,特别是引用[1]中提到的全缓冲、行缓冲和不带缓冲这三种缓冲类型,这应该是第五章的重要内容之一。另外,打开流的函数如fopen、freopen、fdopen也在引用[1]中被提及,这些都是标准I/O的核心函数。因此,我需要将这些内容整合到小结中。 接下来,我需要确保结构清晰,分点列出。可能的结构包括缓冲类型、文件操作函数、流的概念、错误处理等。同时,用户要求使用中文回答,并正确使用LaTeX格式,特别是行内公式用$...$,独立公式用$$...$$。不过在标准I/O的小结中可能公式较少,但如果有相关的示例代码或数学表达式,比如缓冲区大小的计算,可能需要使用。 然后,生成相关问题。根据用户提供的示例,问题应该围绕章节的重点,例如缓冲类型的区别、函数的使用场景、错误处理的方法等。需要确保问题能够帮助用户巩固知识点。 另外,用户提到引用的内容需要自然添加引用标识。引用[1]到[4]中,只有引用[1]和引用[3]可能与标准I/O相关,但引用[3]更多是关于进程组的,可能与当前主题关联不大。因此主要参考引用[1]的内容,并在适当的位置添加标识。 最后,要检查LaTeX语法是否正确,比如使用$int$表示变量时是否正确,是否有遗漏的符号。同时,回答要符合用户给出的结构,先进行知识小结,再列出相关问题。 现在,我需要组织这些信息,确保覆盖第五章的主要知识点,并按照用户的要求呈现。可能遗漏的部分需要确认,比如标准I/O的其他功能,如格式化输入输出、临时文件处理等,但根据提供的引用,用户可能更关注缓冲机制和文件操作。因此,重点放在缓冲类型、文件打开关闭函数、流的概念、以及错误处理上。</think>### APUE第五章 标准I/O 知识小结 #### 一、核心特性 1. **缓冲机制** - **全缓冲**:填满标准I/O缓冲区后才执行实际I/O操作(如磁盘文件操作)[^1] - **行缓冲**:遇到换行符或缓冲区满时执行I/O(如终端输入输出) - **不带缓冲**:直接执行I/O操作(如标准错误流`stderr`)[^1] 2. **流与文件指针** 标准I/O通过`FILE`类型指针操作流,包含文件描述符、缓冲区指针、当前读写位置等元数据。 3. **打开与关闭流** - `fopen`:打开文件并关联流 - `freopen`:重定向流到新文件 - `fdopen`:将文件描述符转换为流 - `fclose`:关闭流并释放缓冲区 #### 二、关键函数 1. **格式化I/O** ```c printf("Value: %d\n", x); // 格式化输出 scanf("%s", buffer); // 格式化输入 ``` 2. **二进制I/O** ```c fread(buffer, size, count, stream); // 读取二进制数据 fwrite(buffer, size, count, stream); // 写入二进制数据 ``` 3. **定位流** - `fseek`:设置文件位置指示器 - `ftell`:获取当前偏移量 - `rewind`:重置到文件起始位置 #### 三、高级特性 1. **临时文件** ```c FILE *tmpfile(void); // 创建临时文件(自动删除) char *tmpnam(char *s); // 生成唯一临时文件名 ``` 2. **缓冲控制** ```c setvbuf(stream, buf, mode, size); // 自定义缓冲模式 ``` 3. **错误处理** - `ferror`:检测流错误标志 - `feof`:检测文件结束标志 - `clearerr`:清除错误标志 $$ \text{缓冲区大小计算公式:}\quad \text{BufferSize} = \text{BUFSIZ} \times n \quad (n \in \mathbb{N}^+) $$
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值