您的位置:首页 > 编程语言 > C语言/C++

C语言I/O文件操作总结

2013-03-09 11:49 281 查看
/******************************************************************

*** 标准I/O库

*** 对于标准I/O库,它们的操作是围绕流(stream)进行的

*** 用标准I/O库打开或者创建一个文件时,我们就将一

*** 个流和一个文件相关联

******************************************************************/

对于ASCII字符集,一个字符用一个字节表示。对于国际字符集,一个字符可用多个字节表示。标准I/O文件流可用于单字节或多字节(“宽”)字符集。流的定向决定了所读、所写字符是单字节还是多字节。当一个流最初被创建时,它并没有定向。如若在未定向的流上使用一个多字节I/O函数,则将该流的定向设置为宽定向的。若在未定向的流上使用一个单字节I/O函数,则将该流的定向设置为字节定向的。

只有两个函数可以改变流的定向。freopen函数清除一个流的定向;fwide函数设置流的定向。

#include<wchar.h>

int fwide(FILE *fp,int mode);

若mode参数值为负,fwide将试图使指定的流是字节定向的。

若mode参数值为正,fwide将试图使指定的流是宽定向的。

若mode参数值为0,fwide将不试图设置流的定向,但返回标识该流定向的值

三种标准输入、输出、出错:

stdin

stdout

stderr

缓冲:

标准I/O提供了三种类型的缓冲

(1)全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作。对于驻留在磁盘上的文件通常采用全缓冲。在一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc函数获得需使用的缓冲区。

(2)行缓冲。当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。当流涉及一个终端时,通常使用行缓冲。

对于行缓冲有两个限制:

第一、因为标准I/O库用来收集每一行的缓冲区的长度是固定的,所以只要填满了缓冲区,那么即使还没有写一个换行符,也进行I/O操作。

第二、任何时候只要通过标准I/O库要求从一个不带缓冲的流,或者一个行缓冲的流得到数据,那么就会造成冲洗所有行缓冲输出流。

(3) 不带缓冲。标准库不对字符进行缓冲存储。标准出错流通常是不带缓冲的。

void setbuf(FILE *restrict fp, char *restrict buf);

int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);

setbuf函数打开或者关闭缓冲机制,参数buf是一个指定长度为BUFSIZ的缓冲区。buf设置为NULL ,则表示关闭缓冲区。

setvbuf函数可以精确的指定所需的缓冲类型。这是用mode参数实现的:

mode:

_IOFBF 全缓冲

_IOLBF 行缓冲

_IONBF 不带缓冲

如果指定一个不带缓冲区的流,则忽略buf和size参数。如果指定全缓冲或行缓冲,则buf和size可以选择的指定一个缓冲区和长度,如果该流是带缓冲的,而buf是NULL,则标准I/O库将自动的分配适当长度的缓冲区。适当长度指的是由常量BUFSIZ所指定的值。

打开流:

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);

三个函数成功返回文件指针,失败返回NULL

(1)、fopen打开一个指定的文件

(2)、freopen在一个指定的流上打开一个指定的文件,如若该流已经打开,则先关闭该流。若该流已经定向,则freopen清除该定向。此函数一般用于将一个指定的文件打开为一个预定义的流:标准输入、标准输出或标准出错;

(3)、fdopen获取一个现有的文件描述符,并使一个标准的I/O流与该描述符相结合。此函数常用于由创建管道和网络通信通道函数返回的描述符。因为这些特殊类型的文件不能用标准I/O fopen打开,所以我们必须先调用设备专用的函数以获得一个文件描述符,然后用fdopen使一个标准I/O流与该描述符相关联。

type参数是对该I/O流的读、写方式

读和写流:

一旦打开了流,则可以在三种不同类型的非格式I/O中进行选择,对其进行读写:

1.每次一个字符的I/O。 一次读或写一个字符,如果流是带缓冲的,则标准I/O函数会处理所有缓冲。

2.每次一行的I/O。 如果想要一次读或者写一行数据,则适用fgets和fputs。每行都以一个换行符终止。当调用fgets时,应说明能处理的最大行长。

3.直接I/O。fread和fwrite函数支持这种类型的I/O。每次I/O操作读或写某种数量的对象,而每个对象具有指定的长度。这两个函数常用于从二进制文件中每次读或写一个结构。

一、每次一个字符的I/O:

1.输入函数:

int getc(FILE *fp);

int fgets(FILE *fp);

int getchar(void); //等价于getc(stdin)

这三个函数成功则返回下一个字符,到达文件尾或者出错返回EOF 为了 区分不同情况必须调用一下函数:

int ferror(FILE *fp);

int feof(FILE *fp);

成功返回非零,否则返回0

在大多数实现中,为每个流在FILE对象中维持了两个标志:

出错标志 和文件结束标志

void clearerr(FILE *fp);//清空错误标志和文件结束标志:

从流中读取数据之后,可以调用ungetc将字符再压送会流中

int ungetc(int c,FILE *fp); //成功返回c 否则返回EOF

2.输出函数:

int putc(int c,FILE *fp);

int fputc(int c,FILE *fp);

int putchar(int c);

三个函数成功返回c 失败返回EOF

二、每次一行的I/O

1.输入函数:

char *fgets(char *restrict buf,int n,FILE *restrict fp);

char *gets(char *buf); //从标准输入读。

两个函数成功返回buf,失败返回NULL

fgets 需要指明缓冲区buf的长度n,此函数一直读到换行符为止,读入的数据不能超多n-1个字符,否则读入的将是一个不完整的字符串。buf以NULL结尾。

2.输出函数:

int puts(const char *str);//将一个以null结尾的字符串写到标准输出,null不写出。

int fputs(const char *restrict str,FILE *fp);

两个函数成功返回非负值,出错返回EOF

三、二进制I/O

size_t fread(void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);

size_t fwrite(const void *restrict ptr, size_t size, size_t nobj, FILE *restrict fp);

两个函数返回成功读取或者写入的对象数。

ptr 为要读入或者写入的数据缓冲区, size为 每个对象的字节数, nobj为要读取或者写入的个数,fp为指定的流。

四、格式化I/O

1.格式化输出:

int printf(const char *restrict format, ...);

int fprintf(FIlE *restrict fp, const *restrict format, ...);

//两个函数 成功返回输出字符数,出错返回负值。

int sprintf(char *restrict buf,const char *restrict format, ...);

int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);

//两个函数 成功返回存入buf中的字符数,若编码出错则返回负值。

2.格式化输入:

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, ...):

成功返回输入的项数,否则返回EOF

五、 定位流

有三种方式定位标准I/O流

1. ftell和fseek函数:

long ftell (FILE *fp);//成功返回当前文件位置,出错返回-1

int fseek (FILE *fp, long offset, int whence); //成功返回0,失败返回非零值

void rewind(FILE *fp);//将流设置到文件的起始位置

whence 的取值:

SEEK_SET---------表示从文件的起始位置开始

SEEK_CUR---------表示从文件的当前位置开始

SEEK_END---------表示从文件的结束位置开始

offset 值可正可负;

2. ftello 和 fseeko函数:

off_t ftello(FILE *fp);//成功返回当前文件位置,出错返回-1

int fseeko(FILE *fp, off_t offset, int whence);//成功返回0,失败返回非零值

和ftell与fseek函数相同;

3. fgetpos和fsetpos函数

int fgetpos(FILE *restrict fp, fpos_t *restrict pos);

int fsetpos(FILE *fp, const fpos_t pos);

两个函数成功返回0,失败返回非零值

fgetpos将文件位置指示器的当前值存入有pos指向的对象中。在以后调用fsetpos时,可以用此值将流重新定位到该位置。

六、其他

int fileno(FILE *fp); //返回与该流相关联的文件描述符

临时文件:

char *tmpnam(char *ptr);//返回唯一路径名的指针

FILE *tmpfile(void);//成功返回文件指针,出错返回NULL

tmpnam函数产生一个与现有文件名不同的一个有效路径名字符串。每次调用都产生一个不同的路径名。最多调用TMP_MAX次。

若ptr是NULL,则所产生的路径名存放在一个静态区中,指向该静态区的指针作为函数值返回,下一次调用tmpnam时,会重写该静态区(这意味着,如果我们调用此函数多次,而且想保存路径名,则我们应当保存该路径名的副本,而不是指针的副本)。若ptr不是NULL,则认为它指向长度至少时L_tmpnam个字符的数组(常量L_tmpnam定义在头文件stdio.h中),所产生的路径名存放在该数组中,ptr也作为函数值返回。

tmpfile创建一个临时二进制文件(类型wb+),在关闭文件或者程序结束时将自动删除这种文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: