IO操作-标准IO
一、标准IO涉及到的函数
1.fopen函数
功能:使用标准IO接口打开文件
使用格式:FILE *fopen(const char *pathname, const char *mode);
参数:@pathname:文件的路径和名
@mode:打开方式 包括下面六种
r和w分别表示只读和只写,只读用于打开文件,光标定位在文件的开头。只写光标也是定位在开头,并可以向文件写入数据,如果文件不存在,读操作会创建一个新文件,或者清空文件从头开始写入。
r+和w+都表示以读写的形式操作文件,只是w+会在没有该文件时创建一个文件,并清空文件中的内容从头写入
a和a+都表示以追加的方式打开文件,光标都会落到文件结尾,且都会在文件不存在时创建新文件,但a+如果执行读操作就会从开头读,只有追加时从结尾写。
返回值:成功返回到FILE指针,失败返回NULL,置位错误码。
2.fclose函数
作用:关闭文件
格式:int fclose(FILE *stream)
参数:@stream:文件名
返回值:成功返回0,失败返回EOF置位错误码
3.fgetc和fputc函数
fgetc():
每次都会从文件中读取一个字符并将其打印,每打印一个字符,光标就回向后移动一位,这样就形成了连续打印文件字符。
fp=fopen("1.c","r+");
fgetc('0',fp);
fputc():
fputc函数和fgetc函数相反,每次都会向文件中写入一个字符,每写入一个字符后光标就回向后移动一位。
fputc('1',fp);
4.fgets/fputs函数
char *fgets(char *s, int size, FILE *stream);
功能:从文件中读取字符串
参数:@s:存储读取到的字符首地址
@size:想读取的大小
@stream:文件指针
返回值:成功返回s,失败返回NULL
int fputs(const char *s, FILE *stream);
功能:向文件中写字符串
参数:@s字符串首地址;
@stream文件指针
返回值:成功返回大于0的值,失败返回EOF
5.fread/fwrite函数的介绍
fread(void *ptr,size_t size,size_t nmemb, FILE *stream);
功能:从文件中读取数据写入ptr中。
参数:@ptr用来存储读取到的数据地址;
@size每一项的大小;
@nmemb项目个数;
@stream文件指针
返回值:成功返回读取到的个数。
如果size是1,返回的项目个数就是字节的个数。
失败返回小于项目的个数或者是0
如果是失败需要通过ferror或者feof判断是那种错误
if(ferror(fp)){
printf("读的时候发生了错误");
}
if(feor(fp)){
printf("读取到文件的结尾了");
}
fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:将ptr中的数据写入到文件中
参数:@ptr写数据首地址;
@size每一项大小;
@nmemb项目个数;
@stream文件指针
返回值:成功返回写入项目的个数;
失败或者到文件结尾了返回小于项目个数或者是0
6.sprintf/snprintf/fprintf函数
sprintf(char *str, const char *format, …);
功能:将字符串格式化到str中(sprintf在越界输入的时候会发生错误)
参数:@str存储格式化后的参数和字符串;
@format 可变参数和printf一样
返回值:成功后返回格式化后的字符的个数,如果遇到输出错误,则返回负值。
snprintf(char *str, size_t size, const char *format, …);
功能:将字符串格式化到stream对应的文件中
参数:@str存储格式化后的参数和字符串;
@format 可变参数和printf一样
返回值:成功返回后格式化的字符个数,如果遇到输出错误,则返回负值。
fprintf(FILE *stream, const char *format,…);
功能:将字符串格式化到stream文件中
参数:@stream文件指针;
@format 可变参数和printf一样
返回值:成功后返回格式化的字符个数,如果遇到输出错误,则返回负值。
7.fseek/ftell/rewind函数
int fseek(FILE *stream, long offset, int whence);
功能:用来设置光标的位置
参数:文件指针;设置到哪里(偏移量);从哪里开始设置
>0 向后偏移 SEEK_SET(开头)
=0 不偏移 SEEK_CUR(当前位置)
<0 向前偏移 SEEK_END(结尾)
long ftell(FILE *stream);
功能:获取光标到开头的值(单位字符)
参数:文件指针
返回值:成功返回光标当前位置到开头的字符个数,失败返回-1置位错误码
void rewind(FILE *stream);
功能:将光标设置到开头(类似于fseek(fp,0,SEEK_SET));
参数:文件指针
二、错误码问题
1.获取错误码
错误码是因为用户空间发生错误后从内核中调用的函数来提醒用户错误地点和错误原因的提示码。
头文件#include<errno.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, const char* argv[])
{
FILE* fp;
fp = fopen("./hello.txt","r");
if(fp == NULL){
printf("fopen file error\n");
printf("errno = %d\n",errno);
return -1;
}
return 0;
}
2.将错误码转换成错误信息
在程序出错时,系统返回的错误码并未直接翻译成错误信息所以错误码如果想要准确的提醒用户需要转换为错误信息,方便用户能够准确理解。
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main(int argc, const char* argv[])
{
FILE* fp;
fp = fopen("./hello.txt", "r");
if (fp == NULL) {
printf("fopen file error\n");
printf("errno = %d\n", errno);
// strerror就是将错误码转换为错误信息字符串
//通过printf("%s",)来打印输出错误信息
printf("errmsg = %s\n", strerror(errno));
return -1;
}
return 0;
}
char *strerror(int errnum);
功能:将错误码转换为错误信息
参数:@errnum 错误码
返回值:错误信息的提示字符串
3.直接打印错误信息
利用perror函数可以直接输出错误信息
void perror(const char *s);
功能:直接输出错误信息
参数:你自己输入的出错时的提示信息
无返回值
#include <errno.h>
#include <stdio.h>
#include <string.h>
int main(int argc, const char* argv[])
{
FILE* fp;
if((fp = fopen("./hello.txt", "r"))==NULL){
perror("为打开文件失败了");
return -1;
}
return 0;
}
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define PRINT_ERR(msg) \
do { \
perror(msg); \
return -1; \
} while (0)
//将其定义成宏方便调用。
int main(int argc, const char* argv[])
{
FILE* fp;
if ((fp = fopen("./hello.txt", "r")) == NULL)
PRINT_ERR("fopen hello.txt error");
return 0;
}
可以将其封装进头文件中方便调用
三、缓存区问题
1.缓存区类型以及缓存区大小
全缓存:和文件操作相关就是全缓存,大小是4kb是4096b
行缓存:和终端相关的操作就是行缓存,大小是1kb是1024b
无缓存:标准出错stderr 0
2.刷新时机
行缓存刷新时机
1.当程序结束的时候会刷新行缓存
2.当行缓存遇到换行符的时候会刷新缓冲区
3.当使用fflush的时候,会刷新缓冲区
4.当关闭文件指针的时候也会刷新缓冲区
5.当行缓存(1024)满也会刷新缓冲区
6.当输入和输出发生切换的时候也会刷新缓冲区
全缓存刷新时机
1.程序结束会刷新全缓存
2.关闭文件也会刷新全缓存
3.fflush也会刷新全缓存
4.当缓存区满(4096)会刷新全缓存
5.输入输出发生切换的时候也会刷新缓存区
刷新顺序:用户程序------>全缓存–刷新缓存区–>文件