一. 基本流操作函数
#include<stdio.h>
#include<wchar.h>
int fwid(FILE *fp, int mode); //指定流宽带
void setbuf(FILE *restrict fp, char *restrict buf); //打开或关闭缓冲机制
void setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size); //更改缓冲模式
/* mode 参数:
_IOFBF 全缓冲
_IOLBF 行缓冲
_IONBF 不带缓冲
*/
int fflush(FILE *fp); //更新缓冲区
FILE *fopen(const char *restrict pathname, const char *restrict type); //打开标准I/O流
int fclose(FILE *fp); //关闭标准I/O流
二. 格式化I/O函数
int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
三. 临时文件创建函数
#include<stdlib.h>
char *tempnam(char *ptr); //创建有效路径名
FILE *tempfile(void); //创建文件
/*以上存在缺点,及返回目录和创建文件期间有一个时间缺口,可能会重复创建*/
/*替代函数*/
char *mkdtemp(char *template); //创建目录
int mkstemp(char *template); //创建文件
四. 内存流操作
操作函数:
#include<stdio.h>
#include<wchar.h>
FILE *fmemopen(void *restrict buf, size_t size, const char *restrict type);
FILE *open_memstream(char **bufp, size_t *sizep);
FILE *open_wmemstream(wchar_t **bufp, size_t *sizep);
注意点:
一:fmemopen函数在缓冲区第一个字符处设置null,必须使用fflush等函数才能输出。
二:buf参数用null指针无意义,我们无法获取fmemopen自动分配的地址来对数据进行操作。
三:使用fclose, fflush, fseek, fseeko及fsetpos时都会在当前位置加null
#include "apue.h"
#define BSZ 48
int
main()
{
FILE *fp;
char buf[BSZ];
memset(buf, 'a', BSZ-2);
buf[BSZ-2] = '\0';
buf[BSZ-1] = 'X';
if ((fp = fmemopen(buf, BSZ, "w+")) == NULL) //创建缓冲区
err_sys("fmemopen failed");
printf("initial buffer contents: %s\n", buf);
fprintf(fp, "hello, world");
printf("before flush: %s\n", buf);
fflush(fp);
printf("after fflush: %s\n", buf); //这里开始才有输出
printf("len of string in buf = %ld\n", (long)strlen(buf));
memset(buf, 'b', BSZ-2);
buf[BSZ-2] = '\0';
buf[BSZ-1] = 'X';
fprintf(fp, "hello, world");
fseek(fp, 0, SEEK_SET);
printf("after fseek: %s\n", buf);
printf("len of string in buf = %ld\n", (long)strlen(buf));
memset(buf, 'c', BSZ-2);
buf[BSZ-2] = '\0';
buf[BSZ-1] = 'X';
fprintf(fp, "hello, world");
fclose(fp);
printf("after fclose: %s\n", buf);
printf("len of string in buf = %ld\n", (long)strlen(buf));
return(0);
}
四. 部分习题
5.6 程序自动输出提示信息的原因
在交互式程序中,使用行缓冲,每次调用 fgets() 时系统自动冲刷缓冲区。