《APUE》笔记-第五章-标准I/O库

来源:互联网 发布:库房库存数据分析 编辑:程序博客网 时间:2024/06/05 20:34
#include <stdio.h>

FILE *fopen(const char *restrict pathname, const char *type);
FILE *freopen(const char *restrict pathname, const char *type, FILE *restrict fp);//将一个指定的文件打开为一个预定义的流
FILE *fdopen(int fd, const char *type);
//成功,返回文件指针;失败,返回NULL

int fwide(FILE *fp, int mode);
//<0, 字节定向;>0,宽定向;=0,未定向

void setbuf(FILE *restrict fp, char *restrict buf);
int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);//_IOFBF,_IOLBF,_IONBF
//成功,返回0;失败,返回非0

int getc(FILE *fp);
int fgetc(FILE *fp);
int getchar(void);
//成功,返回下一个字符;失败,返回EOF

char *fgets(char *restrict buf, int n, FILE *restrict fp);
//成功,返回buf;文件尾或失败,返回NULL

int ungetc(int c, FILE *fp);//将字符c压入流fp
//成功,返回c;失败,返回EOF

int fclose(FILE *fp);
int fflush(FILE *fp);
//成功,返回0;失败,返回EOF

int putc(int c, FILE *fp);
int fputc(int c, FILE *fp);
int putchar(int c);
//成功,返回c;出错,返回EOF

int fputs(const char *restrict str, FILE *restrict fp);
//成功,返回非负值;出错,返回EOF

int fread(char *restrict ptr, size_t size, size_t nobj, FILE *restrict fp); //一次读取一个完整的结构,size:每个对象的大小,nobj:对象的个数
int write(const char *restrict ptr, size_t size, size_t nobj, FILE *restrict fp); //一次写一个完整的结构,size:每个对象的大小,nobj:对象的个数
//返回读写的字节数;

long ftell(FILE *fp);//返回当前偏移量
int fseek(FILE *fp, long offset, int whence);//设置偏移量

void rewind(FILE *fp);//将一个流设置到文件的起始位置


格式化I/O

int printf(const char *restrict format,  ...);
int fprintf(FILE *restrict fp,  const char *restrict format,  ...);
int dprintf(int fd,  const char *restrict format,  ...);
                                                       成功:返回输出字符数;失败,返回负值
int sprintf(char *restrict buf,  const char *restrict format,  ...);
int snprintf(char *restrict buf,  size_t n, const char *restrict format,  ...); //解决sprintf的缓冲区会溢出的问题

成功:返回存入数组的字符数;出错,返回负值


int scanf(const char *restrict format, ...);
int fscanf(FILE *restrict fp, const char *restrict format, ...);
int sscanf(const char *restrict buf, const char *restrict format, ...);


//每个标准的I/O流都有一个与其相关联的文件描述符

int fileno(FILE *fp); //获得fp的fd


写个程序,练习一下:

#include <stdio.h>#include <wchar.h>#include <unistd.h>#include <fcntl.h>#define BUFSIZE 100int main(){        FILE *pfile = NULL;        FILE *pfile2 = NULL;        int fd, n;        char buf[BUFSIZE];        //输出文件file内容到屏幕        fd = open("file", O_RDONLY);        if (fd == -1)        {                printf("open() error\n");                exit(-1);        }        n = read(fd, buf, BUFSIZE);        if (n == -1)        {                printf("read() error\n");                exit(-1);        }        if (write(STDOUT_FILENO, buf, n) != n)        {                printf("write() error\n");                exit(-1);        }        pfile = fopen("file", "r+");        if (pfile == NULL)                exit(-1);        printf("fopen() ok\n");        pfile2 = freopen("newfile", "w", stderr);//将"newfile"设置为标准输出        if (pfile2 == NULL)                exit(-1);        printf("freopen() ok\n");        pfile2 = fdopen(open("newfile", O_RDONLY), "r");        if (pfile2 == NULL)                exit(-1);        printf("fdopen() ok\n");        int status;        status = fwide(pfile, -1);//将流pfile设置为字节定向        if (status >= 0)                exit(-1);        printf("fwide() ok\n");        setbuf(pfile2, NULL);//关闭缓冲        printf("setbuf() ok\n");        status = setvbuf(pfile, buf, _IOFBF, BUFSIZE);        if (status != 0)                exit(-1);        printf("setvbuf() ok\n");        int c = getc(pfile);        if (c == EOF)                exit(-1);        printf("getc() ok, letter from pfile is: %c\n", c);        c = fgetc(pfile);        if (c == EOF)                exit(-1);        printf("fgetc() ok, letter from pfile is: %c\n", c);        printf("enter a letter: ");        c = getchar();//从标准输入读        if (c == EOF)                exit(-1);        printf("getchar() ok, your input is: %c\n", c);        if (ungetc(c, pfile) == EOF)//字母c压入流缓冲区                exit(-1);        printf("ungetc() ok\n");        if (fgets(buf, BUFSIZE, pfile) == NULL)//fgets遇到换行符终止                exit(-1);        printf("fgets() ok, now, buf is: %s\n", buf);        c = 'b';        if (putc(c, pfile) == EOF)                exit(-1);        printf("putc() ok\n");        if (fputc(c, pfile) == EOF)                exit(-1);        printf("fputc() ok\n");        if (putchar(c) == EOF)//输出到屏幕                exit(-1);        printf("\nputchar() ok\n");        if (fputs(buf, pfile) == EOF)                exit(-1);        printf("fputs() ok\n");        fseek(pfile, 0, SEEK_SET);//偏移量设置到文件起始位置        printf("fseek() ok, now offset is: %d\n", ftell(pfile));        if (fread(buf, 1, 5, pfile) != 5)//一次读取5个1字节                exit(-1);        printf("fread() ok\n");        if (fwrite(buf, 1, 5, stdout) != 5)//一次写5个1字节                exit(-1);        printf("\nfwrite() ok\n");        printf("ftell() ok, now offset is: %d\n", ftell(pfile));        rewind(pfile);//将一个流设置到文件的起始位置        printf("rewind() ok, now offset is: %d\n", ftell(pfile));        printf("fileno() ok, fd of pfile is : %d\n", fileno(pfile));//获取流的文件描述符        fseek(pfile, 0, SEEK_END);        fprintf(pfile, "something come from fprintf()\n");//标准输出到流pfile        fclose(pfile);        fclose(pfile2);        return 0;}

结果如下:


第2次运行程序,结果如下:

分析:

1.调用open、read、write输出文件file内容

2.调用fopen流pfile,打开后流pfile和文件file绑定在一起,因为后面要写入流,所以用"r+"

3.调用freopen,将流文件newfile设置为标准错误

4.在文件描述符上打开一个流

5.-1,小于0,设置为字节定向

6.setbuf的参数为NULL,代表关闭缓冲;否则是全缓冲或行缓冲

7.pfile设置为全缓冲,_IOFBF、_IOLBF、_IONBF

8.getc读取一个字符,宏;fgetc读取一个字符,函数;getchar从标准输入读

9.用ungetc压入字符到流的缓冲区中,并未写到底层文件中。

10.fgets一次读取一行,遇到换行符终止;不用gets,因为不能手动设置缓冲区大小,可能会造成缓冲区溢出

11.putc输出一个字符,宏;fputc输出一个字符,函数;fputc输出到标准输出

12.fputs一次输出一行;不用puts,因为不能手动设置缓冲区大小,可能会造成缓冲区溢出

13.ftell返回偏移量,fseek设置偏移量,rewind设置流偏移量到文件起始位置 SEEK_CUR SEEK_SET SEEK_END

14.fread、fwrite用于二进制文件,一次读写指定大小指定数量的对象

15.fprintf标准输出到流

16.关闭流,文件被关闭前,冲洗缓冲区输出数据,丢弃缓冲区输入数据

0 0