说明
参考:《UNIX环境高级编程》中文版第三版
标准IO
标准IO不同于文件IO,它提供了缓冲机制、以优化长度的块执行IO操作等处理方式。
下面是具体的涉及的函数。
#include <stdio.h>
FILE * fopen(const char * pathname, const char * type);
FILE * freopen(const char * pathname, const char * type, FILE * fp);
FILE * fdopen(int fd, const char * type);
打开一个标准IO流。
成功返回文件指针,失败返回NULL。
FILE的格式如下:
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
pathname用来指定文件名。
type指定打开方式,如r/w/a/r+/w+/a+等。其中w/a//w+/a+可用于创建文件。
上述几个函数的区别:
fopen:普通的打开方式;
freopen:在指定的流fp上打开一个指定文件,一般用于将一个指定的文件打开为预定义的流(如stdin/stdou/stderr等);
fdopen:与已有的文件描述符组合使用,常用于创建管道和网络通信通道的函数返回的文件描述符。
#include <stdio.h>
int fclose(FILE * fp);
关闭一个打开的流。
成功返回0,失败返回-1。
#include <stdio.h>
int getc(FILE * fp);
int fgetc(FILE * fp);
int getchar(void);
读取一个字符。
成功返回得到的字符,失败或者已到结尾,返回EOF。
其中getchar() = getc(stdin);
上面函数的返回之中,无论是失败函数到结尾都会返回EOF,为了进行区别,使用了以下的函数:
#include <stdio.h>
int ferror(FILE * fp);
int feof(FILE * fp);
成功返回非0,失败返回0。
这两个函数能够使用的原因是因为在FILE结构体中有出错标志和文件结束标志。
这两个标志可以用下面的函数来清除:
#include <stdio.h>
void clearerr(FILE * fp);
#include <stdio.h>
int ungetc(int c, FILE * fp);
将字符c送回到流中。注意实际上是送回到流的缓冲区中,而不是底层文件或者设备。
#include <stdio.h>
int putc(int c, FILE * fp);
int fputc(int c, FILE * fp);
int putchar(int c);
输出一个字节。
成功返回c,失败返回EOF。
其中putchar(c) = putc(c, stdout);
注意到上述函数中,有getc和fgetc,putc和fputc两种版本,意思是fxxx的版本一定是函数,而不带f的可以是宏来实现。
#include <stdio.h>
char * fgets(char * buf, int n, FILE * fp);
char * gets(char * buf);
输入一行。
成功返回buf,失败或到达文件尾部返回NULL。
gets()从stdin读取数据,由于没有长度控制,容易导致安全问题,所以不建议使用。
fgets()指定了读取数据的长度n,但是实际上读入的字符只有n-1,因为最后要有一个“\0"。
fgets()读取的字符包含换行符。
#include <stdio.h>
int fputs(const char * str, FILE * fp);
int puts(const char * str);
输出一行。
成功返回非负值,失败返回EOF。
str以“\0"结尾,但是不会输出到流中。
puts()写出到stdout中,它不像gets()那样有安全风险,但是因为配套的关系,gets()不用的话,puts()也建议不要使用了。
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nobj, FILE * fp);
size_t fwrite(const void *ptr, size_t size, size_t nobj, FILE * fp);
二进制的读写。
成功返回读写对象的总数nobj,否则都是失败。
上述两个函数的主要用法有以下几种:
1)读写二进制:
int data[10] = {0};
if ( fwrite(&data, sizeof(int), 10, fp) != 10)
printf("error\n");
2)读写结构体:
struct A data;
if ( fwrite(&data, sizeof(struct A), 10, fp) != 10)
printf("error\n");
#include <stdio.h>
int fflush(FILE * fp);
强制冲洗一个流。
成功返回0,失败返回EOF。
如果fp=NULL,则表示冲洗所有的输出流。
#include <stdio.h>
long ftell(FILE * fp);
成功返回文件位置,失败返回-1。
#include <stdio.h>
int fseek(FILE * fp, long offset, int whence);
成功返回0,失败返回-1。
whence的值由如下几种可能:
1)SEEK_SET:从文件头开始;
2)SEEK_CUR:从当前文件位置开始;
3)SEEK_END:从文件尾部开始;
#include <stdio.h>
void rewind(FILE * fp);
相当于fseek(fp, 0, SEEK_SET);