- 标准IO库和FILE指针
- 1.1 标准IO库
- 1.2 FILE指针
- 标准IO库函数
- fopen()
- fread()
- fwrite()
- fclose()
- fseek()
- ftell()
- 示例
- 文件末尾和错误标志的检测与清除
- 文件末尾的检查feof()函数
- 错误标志的检查ferror()函数
- 文件末尾和错误标志的清除clearerr()函数
- 示例
1 标准IO库和FILE指针
1.1 标准IO库
标准IO库即是标准的C库中用于IO操作的函数,例如读写操作的函数,这些函数相关定义都在<stdio.h>头文件中,所以使用这些函数需要包含头文件<stdio.h>。
标准C库IO操作函数(fopne()、fread()、fwrite()、fclose()、flseek())都是系统调用之上封装后的函数,内部也是调用opne()、read()、write()、close()、lseek()等系统调用函数。
标准IO与文件IO区别在于,同为C语言程序,但标准IO是C库函数,文件IO是Linux系统调用,标准IO是文件IO封装而来的,标准IO的可移植性更好,相对于文件IO,不同操作系统的定义,参数,返回值可能不一致,但是对于标准IO来说在不同操作系统的接口定义几乎是一致的。标准IO的性能效率要更好,因为文件IO在用户空间是不带缓存,而标准IO是在用户空间维护字节的stdio缓存区,所以在性能和效率上要更好。
1.2 FILE指针
文件IO的操作函数都是围绕着文件描述符进行运行,例如open函数打开或创建成功后会返回一个文件描述符fd,但对于标准IO库函数来说,使用fopen函数打开或创建成功后会返回一个指向 FILE 类型对象的指针(FILE * );作用相当于文件描述符fd。
FILE是一个结构体的数据类型,其包含了实际的IO文件描述符,指向文件缓存区的指针,缓存区长度、当前缓冲区的字节数、错误标志等。
标准输入0、标准输出1、标准错误2这三个文件描述符在进程每次确定都会打开,只用于文件IO中,但C库中的标准IO是由文件IO封装而来,故也无法使用,
标准输入:指的是计算机系统的标准的输入设备,通常指的是计算机所连接的键盘,进程从标准输入(stdin)文件中得到输入数据; 标准输出:指的是计算机系统中用于输出标准信息的设备,通常指的是计算机所连接的显示器,正常输出数据输出到标准输出(stdout)文件; 标准错误:指的是计算机系统中用于显示错误信息的设备,通常也指的是显示器设备,错误信息输出到标准错误(stderr)文件。
2 标准IO库函数
2.1 fopen()
函数原型:FILE *fopen(const char *path, const char *mode);
输入参数
path:文件打开或者创建的路径,绝对路径或是相对路径。
mode: 指定了对该文件的读写权限,是一个字符串。
返回值:成功返回一个指向 FILE 类型对象的指针(FILE * ),失败则返回NULL。
参数mode的字符串类型
r:只读方式打开文件,相当于open函数的O_RDONLY标志;
r+:可读可写的方式打开文件,相当于open函数的O_RDWR标志;
w:只写方式打开文件,参数path的文件路径存在则将文件长度截断为0;不存在则创建该文件,相当于open函数的 O_WRONLY | O_CREAT | O_TRUNC标志;
w+:可读可写的方式打开文件,参数path的文件路径存在则将文件长度截断为0;不存在则创建该文件,相当于open函数的 O_RDWR | O_CREAT | O_TRUNC标志;
a:只写方式打开文件,打开文件在末尾开始写入,文件不存在则创建,相当于open函数的 O_WRONLY | O_CREAT | O_APPEND标志;
a+:可读可写的方式打开文件,打开文件在末尾开始写入,文件不存在则创建,相当于open函数的 O_RDWR | O_CREAT | O_APPEND标志;
2.2 fread()
函数原型:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
输入参数
ptr:读取到的数据放入参数ptr指向的缓冲区;
size:读取的每个数据项的字节大小;
nmemb:读取的数据项个数;
stream:FILE指针。
返回值:成功时返回读取到的数据项的数目(总共读取的数据大小为 nmemb * size 个字节),如果发生错误或到达文件末尾,则 fread()返回的值将小于参数nmemb,可以使用ferror()或feof()判断是发生错误还是到达文件末尾。
2.3 fwrite()
函数原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
输入参数
ptr:ptr指向的被写入的数据缓冲区;
size:写入的每个数据项的字节大小;
nmemb:写入的数据项个数;
stream:FILE指针。
返回值:成功时返回写入的数据项的数目(总共读取的数据大小为 nmemb * size 个字节),如果发生错误,则 fwrite()返回的值将小于参数 nmemb(或者等于 0)。
2.4 fclose()
函数原型:int fclose(FILE *stream);
输入参数 stream:FILE指针。
返回值:成功返回0,失败返回-1。
2.5 fseek()
函数原型:int fseek(FILE *stream, long offset, int whence);
输入参数
stream:FILE指针。
offset:与 lseek()函数的 offset 参数意义相同。
whence:与 lseek()函数的 whence 参数意义相同。
返回值:成功返回0,错误返回-1。
2.6 ftell()
函数原型:long ftell(FILE *stream);
输入参数
stream:FILE指针。
返回值:成功返回当前读写位置偏移量,错误返回-1。
2.7 示例
将write_buf缓存区数据写入文件a.c,后将文件a.c数据的读取到read_buf #include <stdio.h> #include <stdlib.h>
int main()
{
FILE *fp = NULL;
char write_buf[] = "aaabbbccc"
char read_buf[100] = {0};
int ret;
fp = fopen("./home/a.c","w+");
if(fp == NULL)
{
perror("fopen ERROR");
exit(-1);
}
if(sizeof(write_buf) > fwirte(write,1,sizeof(write_buf),fp))
{
perror(fwrite ERROR);
close(fp);
exit(-1);
}
if(-1 == fseek(fd,0, SEEK_SET))
{
perror(fseek ERROR);
close(fp);
exit(-1);
}
if(sizeof(write_buf) > fread(read,1,sizeof(write_buf),fp))
{
perror(fread ERROR);
close(fp);
exit(-1);
}
if(-1 == (ret = ftell(fp)))
{
perror(ftell ERROR);
close(fp);
exit(-1);
}
printf("%d,%s",ret,read);
close(fp);
exit(0);
}
3 文件末尾和错误标志的检测与清除
3.1 文件末尾的检查feof()函数
feof()函数用于检测参数stream所指文件的end-of-file 标志是否有被设置。
函数原型:int feof(FILE *stream)
输入参数
stream:FILE指针
返回值:end-of-file 标志被设置返回一个非零值,end-of-file 标志没被设置返回0。
3.2 错误标志的检查ferror()函数
ferror()函数用于检测参数stream所指文件的错误标志是否有被设置。
函数原型:ferror(FILE *stream)
输入参数
stream:FILE指针
返回值:错误标志被设置返回一个非零值,错误标志没被设置返回0。
3.3 文件末尾和错误标志的清除clearerr()函数
ferror()函数)用于清除end-of-file标志和错误标志,除了使用 clearerr()显式清除之外,当调用 fseek()成功时,也会清除文件的end-of-file 标志.
file 标志。
函数原型:clearerr(FILE *stream);
输入参数
stream:FILE指针
返回值:无返回值
3.4 示例
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp = NULL;
char read_buf[100] = {0};
int ret;
fp = fopen("./home/a.c","r");
if(fp == NULL)
{
perror("fopen ERROR");
exit(-1);
}
if(-1 == fseek(fd,0, SEEK_END))
{
perror(fseek ERROR);
close(fp);
exit(-1);
}
if(9 > fread(read,1,9,fp))
{
perror(fread ERROR);
close(fp);
exit(-1);
if (feof(fp))
{
printf("end-of-file标志已被设置,已到文件末尾\n\r");
}
clearerr(fp);
}
close(fp);
exit(0);
}