3.1 缓冲
对于标准IO库,它的操作是围绕流来,对于ascii字符,用一个字节表示,国际字符,一般是用多个字符表示,可以使用函数将流改变为宽定向的
int fwide(FILE* fp,int mode)
mode<0 字节定向
mode>0 宽定向
mode=0 不设置,但返回标志该流定向的值
打开一个流之后,返回一个指向FILE对象的指针,通常包括文件描述符,指向用于该流缓冲区的指针,缓冲区的长度,当前缓冲区中的字符数以及出错标志等等。
3个标准IO流,stdin,stdout,stderr
标准io提供下面3种缓冲
(1)全缓冲
在填满缓冲区之后再进行操作
(2)行缓冲
当遇到换行符的时候进行操作,同时只要填满了缓冲区,也会操作
(3)不带缓冲
标准io库不对字符进行缓冲
注意:
标准错误是不带缓冲的
若是指向终端设备的流,则是行缓冲;否则都是全缓冲的
任何时候,都可以强制冲洗一个流
int fflush(FILE* fp)
成功返回0,否则-1
3.2 流操作
写操作统一为:
[]->fp
读操作统一为:
fp->[]
使用下面的函数打开一个标准IO流
//成功则返回文件指针,否则NULL
FILE* fopen(const char* pathname,const char* type)
type:
b 表示二进制
r 读取
w 写入,从头开始
a 写入,往后面添加
r+ 读写打开
w+ 读写打开,但是若没有文件会创建文件,同时文件截断为0
a+ 文件尾打开,每次写都会写到文件的尾端!
FILE* freopen(const char* pathname,const char* type,FILE* fp)
在一个指定的流上打开一个指定的文件
FILE* fdopen(int fd,const char* type)
在一个文件描述符上打开一个文件流,注意该方法不会截断文件,因为描述符已经打开了
关闭文件的方法如下
int fclose(FILE* fp)
成功,返回0,否则,返回EOF(-1)
在文件被关闭之前,冲洗缓冲区中的输出数据,缓冲区中的任何输入数据被丢弃。
当一个进程正常终止时,则所有带未写缓冲数据的标准IO流都被冲洗,所有打开的标准IO流都被关闭
3.2.1 字符操作
读取一个字符
//返回值都是读取到的字符,出错则返回EOF,文件结尾也会返回EOF,所以无法判断出错
int getc(FILE* fp)
最快,可以被当作宏!
int fgetc(FILE* fp)
int getchar(void)
从文件输入流中读取
由于出错或者文件结尾都会返回-1,需要判断出错
int ferror(FILE* fp)
判断读取文件出错,出错则返回真,否则0
int feof(FILE* fp)
判断读取到文件结束,结束则返回真
void clearerr(FILE* fp)
清楚上面两个标记
int ungetc(int c,FILE* fp)
将字符压入流中,成功则返回c,否则返回EOF
压入的字符可以时除了EOF之外的任意字符,不一定要读出的,到文件结尾再压入一个则会清楚EOF标志!
输出一个字符的操作为:
//成功则返回c,否则返回EOF
int putc(int c,FILE* fp)
同样,宏
int fputc(int c,FILE* fp)
int putchar(int c)
输出到输出流
3.2.2 行的流操作
//成功则返回buf,否则到文件结尾或者出错,返回NULL
char* fgets(char* buf,int n,FILE* fp)
每次都会读取一行,\n也会输入到缓冲区中,但是大小不会超过n,注意结尾会加NULL,所以字符数为n-1
若有问题,则下次会继续该行
char* gets(char* buf)
不检查长度,容易有bug,同时该函数不会将\n存入缓冲区中
//成功则返回非负值,否则返回EOF
int fputs(const char* str,FILE* fp)
并不会输出行,即读取到\n也不会结束,NULL结尾不会写出
int puts(const char* str)
将一个以NULL结尾的字符串写出道标准输出,不会到\n就结束,但是每次写完后,会再将一个\n写入到标准输出
3.2.3 二进制IO
//返回读或写的对象数
size_t fread(void* ptr,size_t size,size_t nobj,FILE* fp)
size: 每个数组元素的大小,即sizeof(ptr[0])
nobj: 为欲操作的元素个数,即sizeof(ptr) //如果为数组的话
若返回值小于nobj可能为EOF或者出错
size_t fwrite(const void* ptr,size_t size,size_t nobj,FILE* fp)
写入时的返回值小于nobj则一定时出错
3.2.4 定位流
long ftell(FILE* fp)
成功则返回文件位置,出错返回—1
int fseek(FILE* fp,long offset,int whence)
成功则返回0,否则返回-1
功能类似于lseek,注意返回值不同,而且由于缓冲区的存在不一定完全相同的文件偏移量
offset: <0 前移
>0 后移
whence: (同lseek)
SEEK_SET(0) 开始位置
SEEK_CUR(1) 当前位置
SEEK_END(2) 结尾位置
void rewind(FILE* fp)
将一个流设置到文件起始位置
3.2.5 格式化IO
写操作(格式化输出)[格式化内容]->(fp)等目标
//成功则返回输出字符,出错则返回-(不一定-1)
int printf(const char* format,...)
int fprintf(FILE* fp,const char* format,...)
格式化写入文件
int dprintf(int fd,const char* format,...)
写入到文件描述符的文件中
//成功返回存入数组的字符数,否则返回-
int sprintf(char* buf,const char* format,...)
写入到buf指向的地址中,该函数没有边界检查,会再数组的末尾加一个NULL,但是不包括在返回值中
//返回存入数组的字符数,否则返回-
int snprintf(char* buf,size_t n,const char* format,...)
写入但是带边界检查
读操作(格式化输入)(fp)等内容->[格式化内容]
//返回输入项数,否则返回EOF(出错或者文件末尾)
int scanf(const char* format,...)
int fscanf(FILE* fp,const char* format,...)
从文件中读入相关字符再格式化输入
int sscanf(const char* buf,const char* format,...)
从数组中读取格式化内容输入到...中
3.2.6 内存流
linux 中可以将内存当作文件来操作,来使得那块文件操作异常迅速
//成功则返回流指针,否则返回NULL
FILE* fmemopen(void *buf,size_t size,const char*type)
调用者通过buf和size这两个参数提供一段内存给该函数来实现内存文件流
type的用法同open一样
打开该文件后,文件的相关操作对其流都可以!