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

#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 100

int 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值