APUE第5章标准I/O库 笔记
来源:互联网 发布:成都软件开发工作室 编辑:程序博客网 时间:2024/06/05 04:21
1.系统调用是以文件描述符进行I/O操作的,标准I/O是c语言,是围绕流stream进行的。
2.文件描述符是STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO分别表示标准输入,输出,出错。流是stdin,stdout,stderr。
3.系统函数open,read,write,close等称为无缓冲函数。因为他们处于c标准的I/O缓冲区的底层。无缓冲函数每次读写都要进入内核,调一个系统调用比调一个用户空间函数慢很多,所以在用户空间开辟缓冲区是必要的。
4.用c标准I/O函数时要时刻注意I/O缓冲区和实际文件可能不一致,必要时调用fflush();
5.网络编程时不希望使用缓冲,所以使用系统函数。
6.标准I/O分为3种类型的缓存:行缓存,全缓存,无缓存。
全缓存:当填满缓冲区时才进行实际I/O操作。在一个流上执行第一次I/O操作,通常调用了malloc函数获得要使用的缓存。
行缓存:当在输入和输出中遇到换行时,标准I/O执行I/O操作。行缓存的长度是有限制的,当行满了后也会执行I/O操作。
无缓存:如stderr
ANSIC要求下列缓存特征:
1.当前仅当标准输入输出不涉及交互设备时,才是全缓存的。
2.标准出错决不会是全缓存的。
可以使用下列函数改变流的缓存模式:
void setbuf(FILE *fp,char *buf);
int setvbuf(FILE *fp,char *buf,int mode,size_t size);
setbuf函数具有打开和关闭缓冲机制。为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中)的缓冲区。
通常在此之后该流就是全缓冲的,但是如果该流与一个终端设备相关,那么某些系统也可以将其设置为行缓冲。为了关闭缓冲,可以将buf参数设置为NULL。
setvbuf通过mode设置缓存模式,_IOFBF全缓存,_IOLBF行缓存,_IONBF无缓存。
强制刷新流int fflush( FILE *stream);如果stream是NULL,则刷新所有流。
7.打开流
#include <stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict type);
FILE *freopen(const char *restrict pathname, const char *restrict type, FILE *restrict fp);//使用一个指定的流打开文件,若流已经打开,则先关闭该流。此函数一般用于
将一个指定的文件打开为一个预定义的流。
FILE *fdopen(int filedes, const char *type);//取一个现存的文件描述符与一个流相结合。此函数常用于由创建管道和网络通信通道函数获得的插入符。
type:
type 说明
r或rb 为读而打开
w或wb 把文件截短至0长,或为写而打开
a或ab 添加;为在文件尾写而打开,或为写而创建
r+或r+b或rb+ 为读和写而打开
w+或w+b或wb+ 把文件截短至0长,或为读和写打开
a+或a+b或ab+ 为在文件尾读和写而打开或创建
由于unix不区分二进制文件,所以b是无效的。
int fclose(FILE *fp);//关闭流,刷新缓存中的输出数据,丢弃输入数据,释放缓存。
当以读和写类型打开一个文件时(type中+号),具有下列限制:
如果中间没有fflush、fseek、fsetpos或rewind,则在输出的后面不能直接跟随输入。
如果中间没有fseek、fsetpos或rewind,或者一个输出操作没有达到文件尾端,则在输入操作之后不能直接跟随输出。
8.读和写流
#include <stdio.h>
int getc(FILE *fp);//实现可能是宏,宏的效率比函数快,但参数不能有副作用。
int fgetc(FILE *fp);
int getchar(void);//等价于getc(stdin)
返回值:成功则返回下一个字符,到达文件尾部或出错返回EOF;为了区分要使用ferror或者feof函数
int ferror(FILE *fp);
int feof(FILE * fp);
返回值:条件为真返回非0值,否则返回0;
void cleanerr(FILE *fp);//清除流的出错标志和文件结束标志
int ungetc(int c, FILE *fp);//将字符送回流中
返回值:成功返回c,出错返回EOF;
int putc(int c, FILE *fp)//输出字符,该实现可以是宏
int fputc(int c, FILE *fp);
int putchar(int c);//等价于putc(c,stdout);
9.每次一行I/O
char *fgets(char *restrict buf, int n, FILE *restrict fp);//读取一行但不超过n-1个字符,读入的字符被送入缓存。该缓存以null字符或者换行结尾。成功时
返回字符串,失败返回NULL
char *gets(char *buf);//不推荐
int fputs(const char *restrict str, FILE *restrict fp);//写字符串,成功时返回非负值, 失败时返回EOF
int puts(const char *str);//成功时返回非负值, 失败时返回EOF
10.读写二进制文件,int fread( void *buffer, size_t size, size_t num, FILE *stream );
函数fread()读取[num]个对象(每个对象大小为size(大小)指定的字节数),并把它们替换到由buffer(缓冲区)指定的数组. 数据来自给出的输入流. 函数的返回值是读取的内容数量。
如果返回值小于num,则是发生错误或者到达文件结束。使用feof()或ferror()判断到底发生哪个错误。
int fwrite( const void *buffer, size_t size, size_t count, FILE *stream );fwrite()函数从数组buffer(缓冲区)中, 写count个大小为size(大小)的对象到stream(流)指定的流. 返回值是已写的对象的数量。如果少于count则表示出错。
这两个函数常用方法是读写数组,或者是结构体。
#include<stdio.h>#include<string.h>struct Data{ int a; int b; };int main(void){ FILE*stream; Data msg={1,2}; Data msg2; if((stream=fopen("DUMMY.FIL","w+"))==NULL) { fprintf(stderr,"Cannotopenoutputfile.\n"); return 0; } /*write some data to the file*/ fwrite(&msg,sizeof(Data),1,stream); /*sizeof(char)=1seektothebeginningofthefile*/ fseek(stream,0,SEEK_SET); /*readthedataanddisplayit*/ fread(&msg2,sizeof(Data),1,stream); printf("%d %d\n",msg2.a,msg2.b); fclose(stream); //remove("DUMMY.FIL"); return 0;}
11.定位流long ftell( FILE *stream );//返回当前的文件位置,出错返回-1
int fseek(FILE *fp, long offset, int whence);
函数fseek()为给出的流设置位置数据. origin的值应该是下列值其中之一(在stdio.h中定义):
名称说明SEEK_SET从文件的开始处开始搜索SEEK_CUR从当前位置开始搜索SEEK_END从文件的结束处开始搜索fseek()成功时返回0,失败时返回非零. 你可以使用fseek()移动超过一个文件,但是不能在开始处之前.
void rewind(FILE *fp)//函数rewind()把文件指针移到由stream(流)指定的开始处, 同时清除和流相关的错误和EOF标记.
int fgetpos(FILE *restrict fp, fpos_t *restrict pos)//fgetpos()函数保存给出的文件流(stream)的位置指针到给出的位置变量(pos)中.
pos变量是fpos_t类型的(它在stdio.h中定义)并且是可以控制在FILE中每个可能的位置对象. fgetpos()执行成功时返回0,失败时返回一个非零值
int fsetpos(FILE *fp, const fpos_t *pos)//fsetpos()函数把给出的流的位置指针移到由position对象指定的位置. fpos_t是在stdio.h中定义的. fsetpos()执行成功返回0,失败时返回非零.
12.格式化输出
int printf( const char *format, ... );//printf()的返回值是打印的字符数,如果发生错误则返回一个负值
int fprintf( FILE *stream, const char *format, ... );//fprintf()函数根据指定的format(格式)(格式)发送信息(参数)到由stream(流)指定的文件. fprintf()只能和printf()一样工作. fprintf()的返回值是输出的字符数,发生错误时返回一个负值
int sprintf( char *buffer, const char *format, ... );//sprintf()函数和printf()类似, 只是把输出发送到buffer(缓冲区)中.返回值是写入的字符数量
int vprintf( char *format, va_list arg_ptr );
int vfprintf( FILE *stream, const char *format, va_list arg_ptr );
int vsprintf( char *buffer, char *format, va_list arg_ptr );
13.格式化输入
int scanf( const char *format, ... );//scanf()读取匹配format(格式)字符串的输入. 当读取到一个控制字符, 它把值放置到下一个变量. 空白(tabs, 空格等等)会跳过. 非空白字符和输入匹配, 然后丢弃. 如果是一个在%符号和控制符间的数量, 那么只有指定数量的字符转换到变量中. 如果scanf()遇到一个字符集(用%[]控制字符表示), 那么在括号中的任意字符都会读取到变量中. scanf()的返回值是成功赋值的变量数量, 发生错误时返回EOF
int fscanf( FILE *stream, const char *format, ... );//函数fscanf()以scanf()的执行方式从给出的文件流中读取数据. fscanf()的返回值是事实上已赋值的变量的数,如果未进行任何分配时返回EOF
int sscanf( const char *buffer, const char *format, ... );//函数sscanf()和scanf()类似, 只是输入从buffer(缓冲区)中读取
int fileno(FILE *stream);//取得流的文件描述符
14.临时文件
char *tmpnam( char *name );//tmpnam()函数创建一个独特的文件名并保存在name中. tmpnam()最多可以调用TMP_MAX指定的次数
FILE *tmpfile( void );//函数tempfile()用一个独特的文件名打开一个临时文件,并返回一个到该文件的指针.如果发生错误则返回null,程序结束则自动删除该文件
- APUE第5章标准I/O库 笔记
- apue 第5章 标准I/O库
- 《APUE》笔记-第五章-标准I/O库
- apue 第五章 标准i/o库
- 【APUE】标准I/O库
- APUE 标准I/O库
- APUE------标准I/O库
- apue:标准I/O库
- apue学习笔记(第五章 标准I/O)
- APUE学习笔记——标准I/O库
- apue学习第九天——标准I/O库(第五章)
- 第5章 标准I/O库
- 第5章 标准I/O库
- APUE学习笔记3——第五章——标准I/O库
- APUE学习: 第五章, 标准I/O库
- APUE读书笔记-第五章 标准I/O库
- APUE-第五章学习-标准I/O库-习题
- APUE——Chapter 5:标准I/O库
- C语言条件编译
- Request请求
- hibernate 三种状态详解
- linux下stray \357 in program的解决
- hibernate文件下载方法
- APUE第5章标准I/O库 笔记
- 【Java项目实战】MyEclipse10破解方法
- hdoj 2081 手机短号
- SQL视频总结
- eclipse import re 报错
- RichviewEdit 图文保存操作
- Android error--No implementation found for native Lcomd
- LD_LIBRARY_PATH环境变量的设置
- C++中引用(&)的用法和应用实例