标准I/O
来源:互联网 发布:2选一数据选择器max 编辑:程序博客网 时间:2024/05/17 03:58
标准I/O
流和FILE对象:
文件指针:
File指针:每个被使用的文件都在内存中开辟了一个区域,用来存放文件指针的有关信息,这些信息是保存在一个结构体类型的变量中,该结构体类型由系统定义,取名为FILE。
标准I/O库的所有操作都围绕流(stream)来进行的。在标准I/O中,流用FILE*描述。
流:
定义:所有的I/O操作仅是简单的从程序移进或者移出
分类:二进制流 文本流。
缓冲区文件系统:
目的:尽量减少使用read/write的调用
定义:系统自动的在内存中为每一个正在使用的文件开辟一个缓冲区,从内存想磁盘输出数据必须先先送到内存缓冲区,装满缓冲区在一起送到磁盘中去。从磁盘中读数据,则一次从磁盘文件将一批数据读入到磁盘缓冲区,然后在从缓冲区逐个的将数据送到程序的数据去。
分类:全缓存,行缓存,不缓存
全缓存:
当填满I/O缓存后才进行实际I/O操作,或者满足一定条件后,系统调用malloc来获得所需要的缓冲区域,默认值。
行缓存:
当在输入和输出中遇到新行符(‘\n’)时,进行I/O操作。当流遇到一个终端时,典型的行缓存。
不带缓存:
标准I/O库不对字符进行缓冲,例如stderr。标准出错绝不会是全缓存的。
使用setbuf()和setvbuf()可以进行更改缓存的类型
在任何时刻,可以使用fflush强制刷新一个数据流:int fflush(FILE *p);
标准I/O预定义三个流:stdin stdout stderr
标准I/O库
Fopen fclose
当打开一个流时,标准I/O函数fopen返回一个指向FILE对象的指针。该对象通常是一个结构,它包含了标准I/O库为管理该流所需的所有信息,包括:用于实际I/O的文件描述符、指向用于该缓冲区的指针、缓冲区的长度、当前在缓冲区的字符数以及出错标志等。为引用一个流,需将FILE指针作为参数传递给每个标准I/O函数。
对于标准输入、标准输出和标准出错,他们的文件描述符对应STFIN_FILENO、STDOUT_FILENO和STDERR_FILENO。这三个标准I/O流通过预定义stdin、stdout和stderr加以引用。这三个文件指针以及标准I/O函数都定义在头文件<stdio.h>中。
缓冲
标准I/O库提供缓冲的目的是尽可能减少使用read和write调用次数。提供了三种类型的缓冲:
1)全缓冲:需在填满标准I/O缓冲区后才进行实际I/O操作。
2)行缓冲:当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。
3)不带缓冲:标准I/O库不对字符进行缓冲存储。
一般而言,标准出错是不带缓冲的,打开终端设备的流是行缓冲的,其他所有流则是全缓冲的。当流是全缓冲,但该缓冲区是局部填写时,可用fflush函数冲洗。
可调用下面的函数更改缓冲区类型:
#include<stdio.h>
void setbuf(FILE*stream, char *buf);
int setvbuf(FILE*stream, char *buf, intmode, size_t size);
任何时候,我们都可以强制冲洗一个流:
#include<stdio.h>
int fflush(FILE*stream);
此函数将使该流所有未写的数据都被传送至内核。作为一个特例,如若fp是NULL,则此函数将导致所有输出流被冲洗。
打开流
#include<stdio.h>
FILE *fopen(constchar *path, const char*mode);
FILE *fdopen(intfd, const char *mode);
FILE *freopen(constchar *path, const char*mode, FILE *stream);
这三个函数的区别是:
1) fopen打开一个指定的文件。
2) fropen在一个指定的留上打开一个指定的文件,如若该流已经打开,则先关闭该流。如若该流已经定向,则fopen清除该定向。此函数一般用于将一直指定的文件打开为一个预定义的流:标准输入、标准输出或标准错误。
3) fdopen获取一个现有的文件描述符,并使一个标准的I/O流与该描述符相结合。此函数常用于由创建管道和网络通信函数返回的描述符。因为这些特殊类型的文件不能用标准I/Ofopen函数打开,所有我们必须先调用设备专用函数以获得一个文件描述符,然后用fopen使一个标准I/O与该描述符相关联。
其中的mode参数可以用是以下15种不同的值:
r或rb: 为读打开
w或wb: 把文件截短至0长,或为写而创建
a或ab:添加;为在文件写打开,或为写打开
r+或r+b或rb+: 为读和写打开
w+或w+b或wb+: 把文件截短至0,或为读和写打开
a+或a+b或ab+: 为在文件尾端读和写而打开或创建
#include<stdio.h>
int fclose(FILE*fp);
在文件被关闭之前,冲洗缓冲区中的输出数据。如果标准I/O库已经为该流自动分配了一个缓冲区,则释放缓冲区。
读和写流
一旦打开了流,则可在三种不同类型的非格式化I/O中进行选择,对其读、写操作:
1)每次一个字符是I/O。一次读或写一个字符,如果流是带缓冲区的,则标准I/O函数会处理所有缓冲。
2)每次一行的I/O。如果想要一次读或写一行,则使用fgets和fputs。每行都以一个换行符终止。当调用fgets时,应说明能处理的最大行长。
3)直接I/O。fread和fwrite函数支持这种类型的I/O。
每次一个字符I/O
输入函数:
#include<stdio.h>
int getc(FILE*stream);
int fgetc(FILE*stream);
int getchar(void);
getchar()等价于getc(stdin)。getc和fgetc区别在于getc可被实现为宏,而fgetc则不能实现为宏。
不管是出错还是到达文件尾端,这三个函数都返回同样的值。为了区分出错和到达文件尾端,必须调用ferror和feof函数。
#include<stdio.h>
int feof(FILE*stream);
int ferror(FILE*stream);
这两个函数的返回值:若条件为真则返回非0值,否则返回0。
每个流在FILE对象中维持了两个标志:出错标志和文件结束标志
调用clearerr则清除这两个标志。
void clearerr(FILE*stream);
从流读取数据后,可以调用ungetc将字符再压入回流中。
int ungetc(int c,FILE *stream);
压入回流中的字符以后又可以从流中读出,但读出的字符顺序与压送回的顺序相反。
对于输出函数:
#include<stdio.h>
int putc(int c,FILE *stream);
int fputc(int c,FILE *stream);
int putchar(int c);
与输入函数一样putchar(c)等效于putc(c, stdout)。putc可实现为宏。
每次一行I/O
#include<stdio.h>
char *fgets(char*s, int size, FILE*stream);
char *gets(char*s);
fgets从指定的流读,必须指定缓冲区长度size。此函数一直读到下一个换行符为止,但是不超过n-1个字符,读入的字符被送入缓冲区。该缓冲区以null字符结尾。如若改行(包括最后一个换行符)的字符数超过n-1,则fgets只返回一个不完整的行,但是缓冲区总是以null字符结尾。对fgets的下一次调用会继续读改行。
gets从标准输入读。它是一个不推荐的函数,因为不能指定缓冲区长度,可能造成缓冲区溢出,写到缓冲区之后的存储空间中,从而产生不可预料的后果。
fputs和puts提供每次输出一行的功能。
int fputs(constchar *s, FILE *stream);
int puts(const char*s);
二进制I/O
#include<stdio.h>
size_t fread(void*ptr, size_t size,size_t nmemb, FILE *stream);
size_t fwrite(constvoid *ptr, size_tsize, size_t nmemb, FILE *stream);
以上两个函数可一次读或写整个结构。
定位流
有三种方法定位标准I/O流
1) ftell和fseek。这两个函数要求文件的位置可以存放到一个长整形中。
2) ftello和fseeko。他们可以使文件文件偏移量不一定使用长整形。他们用off_t数据类型代替了长整形。
3) fgetpos和fsetpos。他们使用抽象数据类型fpos_t记录文件的位置。这种数据累心可以定义为记录一个文件的位置所需的长度。
#include<stdio.h>
int fseek(FILE*stream, long offset, intwhence);
long ftell(FILE*stream);
int fseeko(FILE*stream, off_t offset, intwhence);
off_t ftello(FILE*stream);
int fgetpos(FILE*stream, fpos_t *pos);
int fsetpos(FILE*stream, fpos_t *pos);
格式化I/O
输出:
#include<stdio.h>
int printf(constchar *format, ...);
int fprintf(FILE*stream, const char*format, ...);
int sprintf(char*str, const char *format,...);
int snprintf(char*str, size_t size, constchar *format, ...);
输入:
#include<stdio.h>
int scanf(constchar *format, ...);
int fscanf(FILE*stream, const char*format, ...);
int sscanf(constchar *str, const char*format, ...);
fileno函数
标准I/O库最终都要调用I/O系统调用函数。每个标准I/O流都有一个与其相关联的文件描述符,可以对一个流调用fileno函数以获得其描述符。
int fileno(FILE*stream);
临时文件
#include<stdio.h>
char *tmpnam(char*s);
FILE*tmpfile(void);
tmpnam函数产生一个与现有文件名不同的一个有效路径名字字符串。每次调用它,它都产生一个不同的路径名,最多调用TMP_MAX次。
tmpfile创建一个临时二进制文件。
此外还有两个类似的函数:
#include<stdio.h>
char *tempnam(constchar *dir, const char*pfx);
int mkstemp(char*template);
- Java 标准I/O
- 标准 C I/O
- 标准I/O库函数
- 标准I/O缓冲
- 标准I/O库
- 标准I/O库
- 标准I/O开发
- 标准I/O库
- 标准I/O限制
- 标准I/O
- 标准I/O库
- 标准I/O详解
- 标准I/O
- 标准I/O库
- 标准I/O缓冲
- C标准I/O
- 标准I/O库
- 标准I/O操作
- apache php mysql 怎么理解他们工作流程
- LeetCode 217. Contains Duplicate
- 在原生态的zabbix3.0登录界面添加hand登录界面的样式
- 安卓、java常用文件操作(复制,读取,写入,转换等)
- 热衷分享永远不会错
- 标准I/O
- 杂花生树(二十)
- js中&&和||
- LeetCode 350. Intersection of Two Arrays II
- Cookie和Session
- 51nod 1004 n^n的末位数字
- maven中的groupId和artifactId到底指的是什么?
- win32窗口机制之CreateWindowEX
- C语言指针的基本概念