/*****************************************
包含头文件: #include <stdio.h>
#include <wchar.h>
函数原型: int fwide(FILE *fp,int mode);
函数说明: 设置流的定向
注: 若mode为正值,则流试图被设置为宽定向,若mode是负值,则流试图被设置为字节定向,若mode为0,不试图设置流的定向
返回值: 若流是宽定向,返回正值,若流字节定向的,返回负值,若流是未定向的,返回0
*****************************************/
/*****************************************
包含头文件: #include <stdio.h>
函数原型: void setbuf(FILE * restrict fp,char *restrict buf);
函数说明: 可以使用setbuf打开或关闭缓冲机制
注: 为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ的缓冲区,通常在此之后,该流就是全缓冲的了,但是如果该流与一个终端设备相关,那么某些系统也可将其设置为行缓冲的,为了关闭缓冲,将buf设置为NULL
*****************************************/
/*****************************************
包含头文件: #include <stdio.h>
函数原型: int setvbuf(FILE *restrict fp,char restrict buf,int mode,size_t size);
函数说明: 设置流缓冲机制
使用setvbuf,我们可以精确地说明所需的缓冲类型,这是mode参数实现:
_IOBUF 全缓冲
_IOLBF 行缓冲
_IONBF 不带缓冲
注:如果指定一个不带缓冲的流,则buf和size参数会被忽略,如果指定全缓冲或行缓冲,则buf和size可选地指定一个缓冲区及其长度,如果该流是带缓冲的,而buf是NULL,则标准I/O库自动的为该流分配适当长度(BUFSIZ)的缓冲区
返回值: 若成功,返回0,若失败,返回-1
*****************************************/
/*****************************************
包含头文件: #include <stdio.h>
函数原型: int fflush(FILE *fp);
函数说明: 强制冲洗一个流
注:此函数是该流所有未写的数据都传入内核,作为一种特殊情形,若fp是NULL,此函数将导致所有输出流被冲洗
返回值: 若成功,返回0,若失败,返回-1
*****************************************/
/*****************************************
包含头文件: #include <stdio.h>
函数原型: FILE* fopen(const char *restrict pathname,const char *restrict type);
函数说明: 打开pathname指定的一个文件
type 取 r rb w wb a ab r+ r+b rb+ w+ w+b wb+
a+ a+b ab+其中一种
返回值: 若成功,返回文件指针,若失败,返回NULL
*****************************************/
/*****************************************
包含头文件: #include <stdio.h>
函数原型: FILE *freopen(const char * restrict pathname,const char *restrict type,FILE *restrict fp);
函数说明:在一个指定的流上打开一个指定的文件,如若该流已经打开,则关闭该流,若流已经定向,则使用
freopen清除该定向,此函数一般用于指定的文件打开为一个预定义的流:标准输入,标准输出,标准错误
返回值:若成功,返回文件指针,若失败,返回NULL
*****************************************/
/*******************************************************
包含头文件: #include <stdio.h>
函数原型: FILE* fdopen(int fd,const char* type);
函数说明:取一个已有文件描述符,并使一个标准的I/O
流与该描述符相结合(此函数常用于创建管道和网络通信管道函数返回的描述符);
返回值: 若成功,若失败,返回NULL
*****************************************/
/**********************************************************
包含头文件: #include <stdio.h>
函数原型: int fclose(FILE *fp);
函数说明: 关闭一个打开的流
返回值:若成功,返回0,若失败,返回EOF
************************************************************/
实例:5.1.c
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
int main(int argc,char* argv[])
{
if (argc != 2)
{
printf("add <pathname>\n");
exit(0);
}
FILE *fp;
if ((fp = fopen(argv[1],"r")) == NULL)
{
printf("fopen error\n");
exit(0);
}
// 设置全缓冲
int ret1;
if ((ret1 = fwide(fp,5)) <= 0)
{
printf("fwide error\n");
exit(0);
}
printf("ret1 is %d\n",ret1);
//get ret-value
int ret2;
ret2 = fwide(fp,0);
printf("ret2 is %d\n",ret2);
}
/*****************************************************
包含头文件: #include <stdio.h>
函数原型: int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void)
函数说明: 一次读一个字符
getchar(void)相当于getc(stdin),getc通常被实现为宏,fgetc一定是个函数,所以getc通常速度较快,fgetc可作为函数参数。
注:getc参数不应该为具有副作用的表达式
********************************************************/
/*********************************************************
包含头文件: #include <stdio.h>
函数原型: int ferror(FILE *fp);
int feof(FILE *fp);
函数说明: ferror:判断流是否出错
feof: 判断流是否到达文件尾端
返回值: 若条件为真,返回非0,否则,返回0
************************************************************/
/*********************************************************
包含头文件: #include <stdio.h>
函数原型: void clearerr(FILE *fp);
函数说明: 清除文件出错和文件结束标志
********************************************************/
/********************************************************
包含头文件: #include <stdio.h>
函数原型: int ungetc(int c,FILE *fp);
函数说明:从流中读取数据后,调用ungetc将字符再压送回流中。
注:回送的字符不必是上一次读的字符,不能回送EOF,但是当达到文件尾端时仍可以回送一个字符
(一次成功的ungetc调用会清除该流的文件结束标志)
返回值:若成功,返回c,若出错,返回EOF
*********************************************************/
/******************************************************
包含头文件: #include <stdio.h>
函数原型: int putc(int c,FILE *fp);nt
int fputc(int c,FILE *fp);
int putchar(int c);
函数说明: putchar(int c)相当于putc(int c,stdout)
putc(int c,FILE *fp)通常为宏调用,fputc
必须为函数
*****************************************************/
/***************************************************
包含头文件: #include <stdio.h>
函数原型: char* fgets(char *restrict buf,int n,FILE *restrict fp);
char* gets(char* buf);
函数说明: 每次输入一行
注: 对于fgets,必须指定缓冲的长度n,函数一直读到下一个换行符为止,但是不超过n-1个字符,读入的字符被送入缓冲区
gets不推荐使用
返回值: 若成功,返回buf,若达到文件尾端或出错,则返回NULL
**************************************************/
/***************************************************
包含头文件: #include <stdio.h>
函数原型: int fputs(const char *restrict str,FILE *restrict fp);
int puts(const char *str);
函数说明: 每次输出一行
注:函数fputs将一个以null字节终止的字符串写到指定的流,尾端的终止符null不写出
返回值: 若成功,返回非负值,若出错,返回EOF
***************************************************/
实例:5.2.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
while ((c = getc(stdin)) != EOF)
{
if (putc(c,stdout) == EOF)
{
printf("putc error\n");
exit(0);
}
}
if (ferror(stdin))
printf("输入错误\n");
if (feof(stdin))
printf("输入完毕\n");
exit(0);
}
运行:
5.3.c
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 4096
int main()
{
char buf[MAXLINE];
while (fgets(buf,MAXLINE,stdin) != NULL)
{
if (fputs(buf,stdout) == EOF)
{
printf("fputs error\n");
exit(0);
}
}
if (ferror(stdin))
printf("输入错误\n");
if (feof(stdin))
printf("输入完毕\n");
exit(0);
}
运行:
/******************************************************
包含头文件: #include <stdio.h>
函数原型: size_t fread(void *restrict ptr,size_t size,size_t nobj,FILE *fp);
函数说明: 读对象
返回值: 读的对象数
********************************************************/
/********************************************************
包含头文件: #include <stdio.h>
函数原型: int fwrite(const void *restrict ptr,size_t size,FILE *restrict fp);
函数说明: 写对象
返回值: 写的对象数
******************************************************/
实例:
5.4.c
#include <stdio.h>
#include <stdlib.h>
struct Person
{
char* name;
int age;
};
int main(int argc,char* argv[])
{
if (argc != 2)
{
printf("add <pathname>\n");
exit(0);
}
FILE *fp;
if ((fp = fopen(argv[1],"r+b")) == NULL)
{
printf("fopen error\n");
exit(0);
}
printf("writing\n");
struct Person p;
p.name = "Marco";
p.age = 19;
if (fwrite(&p,sizeof(struct Person),1,fp) != 1)
{
printf("fwrite error\n");
exit(0);
}
//设置eof
getc(fp);
if (feof(fp))
printf("write over\n");
clearerr(fp);
fseek(fp,0,SEEK_SET);
printf("reading\n");
struct Person m;
if (fread(&m,fp) != 1)
{
printf("fread error\n");
exit(0);
}
//设置eof
getc(fp);
if (feof(fp))
printf("read error\n");
fclose(fp);
printf("name is %s\n",m.name);
printf("age is %d\n",m.age);
exit(0);
}
运行:
/*******************************************************
包含头文件: #include <stdio.h>
函数原型: long ftell(FILE *fp);
off_t ftello(FILE *fp);
int fgetpos(FILE *restrict fp,fpos_t *restrict pos);
函数说明: 确定流的位置
返回值: 若成功ftell 返回当前文件位置,若出错,返回-1L
若成功,ftello返回当前文件位置,返回
(off_t) – 1
fgetpos,若成功,返回0,若出错返回非0
***************************************************/
/********************************************************
包含头文件: #include <stdio.h>
函数说明: int fseek(FILE *fp,long offset,int whence);
int fseeko(FILE *fp,off_t offset,int whence);
int fsetpos(FILE *fp,const fpos_t *pos);
函数说明: 设置当前文件位置
返回值: fseek:若成功,返回-1
fseeko:若成功,若出错,返回-1
fsetpos: 若成功,返回非0
**********************************************************/
/*********************************************************
包含头文件: #include <stdio.h>
函数原型: int fileno(FILE *fp);
函数说明: 获得一个流的文件描述符
返回值: 返回与该流相关的文件描述符
*******************************************************/
/****************************************************
包含头文件: #include <sdtio.h>
函数原型: char* tmpnam(char *ptr);
FILE* tmpfile(void);
函数说明: 创建临时文件
tmpnam:若ptr是NULL,则产生的路径名存放在一个静态区,指向该静态区的指针作为函数值返回,该静态区可能回重写,所以我们应当保存路径名的副本,而不是指针的副本,若ptr不是NULL,则长度至少是L_tmpnam个字符的数组
tmpfile:创建一个临时二进制文件(类型wb+),在关闭和程序结束时自动删除该文件
******************************************************/
tmpnam已弃用
5.5.c
#include <stdio.h>
#include <stdlib.h>
#define MAXLINE 4096
int main()
{
FILE *fp;
if ((fp = tmpfile()) == NULL)
{
printf("tmpfile error\n");
exit(0);
}
fputs("I'm tmpfile\n",fp);
rewind(fp);
char line[MAXLINE];
if (fgets(line,sizeof(line),fp) == NULL)
{
printf("fgets error\n");
exit(0);
}
fputs(line,stdout);
exit(0);
}
/********************************************************
包含头文件: #include <stdio.h>
函数原型: char* mkdtemp(char* template);
函数说明: 创建一个目录,该目录拥有唯一的一个名字
返回值: 若成功,返回指向目录名的指针,若出错,返回NULL
***************************************************/
/************************************************
包含头文件: #include <stdio.h>
函数原型: int mkstemp(char *template);
函数说明:创建一个拥有唯一名字的文件
返回值: 若成功,返回文件描述符,若出错返回-1
************************************************/
注:template要留XXXXXX(6个X)作占位符
实例:5.6.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
char filename[] = "/home/marco/tmpfieXXXXXX";
int fd;
printf("making file\n");
if ((fd = mkstemp(filename)) < 0)
{
printf("mkstemp error\n");
exit(0);
}
printf("make over\n");
printf("file name is %s\n",filename);
printf("making dir\n");
char dirname[] = "/home/marco/tmpdirXXXXXX";
char *get;
if ((get = mkdtemp(dirname)) == NULL)
{
printf("mkdtemp error\n");
exit(0);
}
printf("make over\n");
printf("dirname is %s\n",get);
exit(0);
}
运行:
/*********************************************************
包含头文件: #include <stdio.h>
函数原型: FILE *fmemopen(void *restrict buf,const char *restrict type);
函数说明: 创建内存流
注:内存流不适合存储二进制数据(二进制数据在尾端之前可能就有NULL字节)
******************************************************/
/****************************************************
包含头文件: #include <stdio.h>
函数原型: FILE *open_memstream(char **bufp,size_t *sizep);
包含头文件: #include <wchar.h>
函数原型: FILE *open_wmemstream(char **bufp,size_t *sizep);
函数说明:open_memstream:创建一个面向字节的流
open_wmemstream: 创建一个面向宽字节的流
这两个函数与fmemopen函数的不同之处在于:
1.创建的流只能写打开
2.不能指定自己的缓冲区,但可以分别通过bufp和sizep参数访问缓冲区地址和大小
3.关闭流需要自行释放缓冲区
4.对流添加字节会增加缓冲区大小
返回值: 若成功,返回流指针,若出错,返回NULL
*******************************************************/
注: 任何时候需要增加流缓冲区中数据量以及调用fclose fflush,fseek,fseeko以及fsetpos时都会在当前位置写入一个null字节
实例:
#include <stdio.h>
#include <stdlib.h>
#include <string.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)
{
printf("fmemopen error\n");
exit(0);
}
fprintf(fp,"hello,world");
printf("before fflush: %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,world");
fseek(fp,SEEK_SET);
printf("after fseek: %s\n",(long)strlen(buf));
memset(buf,'c',BSZ - 2);
buf[BSZ - 2] = '\0';
buf[BSZ - 1] = 'X';
fprintf(fp,world");
fclose(fp);
printf("after fclose: %s\n",(long)strlen(buf));
return 0;
}