zoukankan      html  css  js  c++  java
  • Unix环境高级编程(三)标准I/O库

      标准I/O库是ISO C的标准,在很多操作系统上面都实现。Unix文件I/O函数都是针对文件描述符的,当打开一个文件的时候,返回该文件描述符用于后续的I/O操作。而对于标准I/O库,操作则是围绕流进行,当用标准I/O库打开或者创建一个文件时,使得一个流与文件相关联。标准I/O库使用了缓冲技术,使用缓冲的目的是尽可能减少使用read和write调用次数,但是效率不高。每次进行读写时候需要复制两次数据。第一次是在内核和标准I/O缓冲之间(调用read和write),第二次是在标准I/O缓冲区和用户程序中的行缓冲区之间。提供了三种类型的缓冲:全缓冲、行缓冲和不带缓冲。标准I/O预定义三个文件指针stdin、stdout和stderr。

      当一个流最初被创建的时候,没有定向。可以用fwide函数设置流的定向,freopen函数清除一个流的定向。采用setbuf和setvbuf函数更改缓冲区类型,fflush函数冲洗一个流。

    int fwide(FILE *stream, int mode); //若流是宽字符定向则返回正值,若是字节定向则返回负值,如实为定向的则返回0
    void setbuf(FILE *stream, char *buf);
    int setvbuf(FILE *stream, char *buf, int mode, size_t size);  
    _IONBF  unbuffered  _IOLBF  line buffered  _IOFBF  fully buffered
    int fflush(FILE *fp);
     
    I/O操作函数:
    FILE *fopen(const char *path, const char *mode);  //打开一个指定的文件
    FILE *fdopen(int fd, const char *mode);  //获取一个现有的文件描述符,使得一个I/O流与该描述符先结合,常用于由创建管道和网络通信通道函数返回的描述符。
    FILE *freopen(const char *path, const char *mode, FILE *stream);//在一个指定的流上打开一个指定的文件
    int fclose(FILE* fp);
     
    一次读取一个字符
    int fgetc(FILE *stream);
    int getc(FILE *stream);
    int getchar(void);
     
    一次读取一行
    char *fgets(char *s, int size, FILE *stream);
    char *gets(char *s);
     
    一次写一个字符
    int fputc(int c, FILE *stream);
    int putc(int c, FILE *stream);
    int putchar(int c);
     
    一次写入一行
    int fputs(const char *s, FILE *stream);
    int puts(const char *s);
     
    针对二进制I/O,一般是结构体类型
    size_t fread(void *ptr, size_t size, size_t nmembFILE *" stream );
    size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
     
    文件定位函数
    int fseek(FILE *stream, long offset, int whence); //设置文件的位置
    long ftell(FILE *stream);  //返回当前文件的位置指示
    void rewind(FILE *stream);  //将一个流的位置设置到文件的开始位置
    int fgetpos(FILE *stream, fpos_t *pos); 
    int fsetpos(FILE *stream, fpos_t *pos);
    fgetpos函数将文件指示器的当前值存入有pos指向的对象中,在以后调用fsetpos时,可以使用此值将流重新定位到该位置。
     
    格式化I/O:
    #include <stdio.h>
    int printf(const char *format, ...);
    int fprintf(FILE *stream, const char *format, ...);  //写入到文件
    int sprintf(char *str, const char *format, ...);  //格式化字符串,可以将其他类型转换为字符串
    int snprintf(char *str, size_t size, const char *format, ...);
    #include <stdarg.h>
    int vprintf(const char *format, va_list ap);
    int vfprintf(FILE *stream, const char *format, va_list ap);
    int vsprintf(char *str, const char *format, va_list ap);
    int vsnprintf(char *str, size_t size, const char *format, va_list ap);
     
    #include <stdio.h>
    int scanf(const char *format, ...);
    int fscanf(FILE *stream, const char *format, ...);  //从文件中读取
    int sscanf(const char *str, const char *format, ...);  //可以提取字符串内容,遇到空格停止
    #include <stdarg.h>
    int vscanf(const char *format, va_list ap);
    int vsscanf(const char *str, const char *format, va_list ap);
    int vfscanf(FILE *stream, const char *format, va_list ap);
     
    在Unix系统中,标准I/O库最终都要调用文件I/O,每个标准I/O流都有一个与其相关联的文件描述符。一个流可以通过调用fileno函数获取其描述符。
    int fileno(FILE *fp)  //在调用dup和fcntl函数的时候用到
    临时文件创建函数tmpnam和tepfile
    char *tmpnam(char *s);
    FILE *tmpfile(void);
    针对标准I/O写个程序进行练习,程序如下:
    复制代码
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <wchar.h>
     5 
     6 #define BUFSIZE 1024
     7 
     8 int main()
     9 {
    10     char *filename = ".//test.log";
    11     char buf[BUFSIZE];
    12     char line[100];
    13     FILE *fp;
    14     memset(line,0,100);
    15     //打开文件,不存在则创建
    16     fp = fopen(filename,"w+");
    17     if(fp == NULL)
    18     {
    19         perror("fopen() error");
    20         exit(-1);
    21     }
    22     //设置为字节宽度
    23     if(fwide(fp,-1) < 0)
    24         printf("byte stream
    ");
    25     //设置为行缓冲
    26     setvbuf(fp,buf,_IOLBF,BUFSIZE);
    27     printf("Enter file content:
    ");
    28     gets(line);
    29     printf("write to file.
    ");
    30     fputs(line,fp);
    31     close(fp);
    32      fp = fopen(filename,"r+");
    33     if(fp == NULL)
    34     {
    35         perror("fopen() error");
    36         exit(-1);
    37     }
    38     printf("read from file.
    ");
    39     fgets(line,99,fp);
    40     printf("%s
    ",line);
    41     close(fp);
    42     return 0;
    43 }
    复制代码

    测试结果如下:

  • 相关阅读:
    聊聊WS-Federation
    用双十一的故事串起碎片的网络协议(上)
    责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
    最小化局部边际的合并聚类算法(中篇)
    最小化局部边际的合并聚类算法(上篇)
    UVaLive 7371 Triangle (水题,判矩形)
    UVaLive 7372 Excellence (水题,贪心)
    POJ 3312 Mahershalalhashbaz, Nebuchadnezzar, and Billy Bob Benjamin Go to the Regionals (水题,贪心)
    UVa 1252 Twenty Questions (状压DP+记忆化搜索)
    UVa 10817 Headmaster's Headache (状压DP+记忆化搜索)
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8465960.html
Copyright © 2011-2022 走看看