您的位置:首页 > 产品设计 > UI/UE

《APUE》读书笔记—第五章标准I/O库

2012-12-14 10:54 316 查看
  标准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写个程序进行练习,程序如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>

#define BUFSIZE 1024

int main()
{
char *filename = ".//test.log";
char buf[BUFSIZE];
char line[100];
FILE *fp;
memset(line,0,100);
//打开文件,不存在则创建
fp = fopen(filename,"w+");
if(fp == NULL)
{
perror("fopen() error");
exit(-1);
}
//设置为字节宽度
if(fwide(fp,-1) < 0)
printf("byte stream\n");
//设置为行缓冲
setvbuf(fp,buf,_IOLBF,BUFSIZE);
printf("Enter file content:\n");
gets(line);
printf("write to file.\n");
fputs(line,fp);
close(fp);
fp = fopen(filename,"r+");
if(fp == NULL)
{
perror("fopen() error");
exit(-1);
}
printf("read from file.\n");
fgets(line,99,fp);
printf("%s\n",line);
close(fp);
return 0;
}


测试结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: