文件操作函数初识
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、文件操作步骤与方法
在讲解文件操作函数前,首先要了解什么是文件。文件通常是在磁盘或者固态硬盘上的一段已命名的存储区。在C语言中把文件看作是一些列连续的字节,每个字节都能被单独读取。文件可以文本文件的形式和二进制文本的形式存储,在二进制模式中,程序可以访问文件的每个字节。一个文件要有唯一的文件标识符以便于系统和用户识别。
1.打开文件
要想对一个文件进行操作,就需要先打开一个文件,创建文件指针(类型是 FILE *类型,该函数声明在 stdio.h 中)并把指针与特定文件名相关联。随后代码就可以使用这个指针(而不是文件名)来操作该文件。
函数原型:
FILE * fopen(const char * filename,const char * mode);
- 参数 const char * filename : 代打开文件的名称(包含该文件名的字符串地址);
- 参数 const char * mode: 一个c字符串,指定待打开文件的模式;
- 返回值 : 文件打开成功后,返回文件的指针(file name),其他文件操作函数可以使用这个指针指定该文件;文件指针的类型是指向FILE的指针,其并不指向实际的文件,它指向一个包含文件信息的数据对象。如果文件打开失败则返回NULL;(在打开文件后,最好判断文件打开是否成功)
模式 | 含义 | 如果指定文件不存在 |
---|---|---|
" r " | 以读模式打开文件 | 出错 |
" w " | 以写模式打开文件 | 建立一个新文件 |
" a " | 以写模式打开文件,在文件尾添加数据 | 出错 |
" r+ " | 以更新模式打开文件,可读可写 | 出错 |
" w+ " | 以更新模式打开文件,可读可写 | 建立一个新文件 |
- fopen函数如果是以写的形式打开,文件如果不存在,会创建这个文件,文件如果存在,会清空文件的内容
- fopen函数如果是以读的形式打开,文件不存在打开失败
文件打开成功后,C程序会自动打开3种标准文件:他们被称为标准输入、标准输出、和标准错误输出;
标准文件 | 文件指针 | 通常使用的设备 |
---|---|---|
标准输入 | stdin | 键盘 |
标准输出 | stdout | 显示器 |
标准错误输出 | sterr | 显示器 |
- 在默认情况下,标准输入是系统的普通输入设备,通常为键盘,标准输出和标准错误输出是系统的普通输出设备,通常为显示屏;
- 标准输入为程序提供输入,它是getchar()、scanf()使用的文件。程序通常输出到标准输出,它是putchar()、puts()、printf()使用的文件;
- 标准错误输出提供了一个逻辑上不同的地方来发送错误消息。
例:
int main()
{
FILE * fp = fopen ("test.txt", "w+"); //1、打开文件
fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014); //2、文件读写
fclose(fp); //3、关闭文件
return 0;
}
2.文件读写
在文件打开成功后,由fopen()函数返回的文件指针(句柄)来对文件进行相应的操作:
1.字符输入:fgetc()、字符输出:fputc()函数
字符输入:fgetc()、字符输出:fputc()函数适用于所有的输入流、输出流;
int fgetc(FILE *stream)
- stream : 这是指向 FILE 对象的指针,该 FILE 对象标识了要在上面执行操作的流。
- 返回值: 到达文件末尾或发生读错误,则返回 EOF。
从文件中读取数据的程序在读到文件结尾时要停止,fgetc()函数在读取一个字符后发现是文件的结尾,将返回一个特殊值EOF,判断其返回值可以判断是否到达文件尾:
例:
为了避免读到空文件,应该使用while()循环,(不能使用do while 循环)进行文件输入.
//方法一:
FILE * fp =fopen("test.txt","r");
int ch = fgetc(fp); //获取初始值
while(ch != EOF) //判断条件
{
printf("%c",ch); //将其输出
ch = fgetc(fp); //获取下一个输入
}
//以上代码可以简化成
FILE * fp =fopen("test.txt","r");
int ch; //获取初始值
while((ch = fgetc(fp)) != EOF) //ch = fgetc(fp)是while条件的一部分,在程序进入循环之前就读取了文件
{
printf("%c",ch);
}
在设计函数时千万不能设计成下面这样:
FILE * fp =fopen("test.txt","r");
int ch;
while(ch != EOF) //局部变量未初始化,该值不确定
{
printf("%c",ch); //将其输出
ch = fgetc(fp); //获取下一个输入
}
上面的函数存在两个问题,会出现未知的错误:
- ch首次与EOF比较时,其值未确定;
- 如果getc()返回EOF,该循环会把EOF作为一个有效字符处理.
int fputc(int char, FILE *stream)
- char :这是要被写入的字符。该字符以其对应的 int 值进行传递。
- stream: 这是指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符的流。
- 返回值:如果没有发生错误,则返回被写入的字符。如果发生错误,则返回 EOF,并设置错误标识符。
fputc()函数的使用方法如下:
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;//失败返回
}
//写文件
int i = 0;
for (i = 'a'; i <= 'z'; i++)
{
fputc(i, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
2.格式化输入:fscanf()、格式化输出:fprintf()函数
格式化输入:fscanf()、格式化输出:fprintf()函数适用于所有的输入流和输出流
fscanf()、fprintf()函数与scanf() printf()函数相似.区别在于:文件I\O函数要用FILE指针指定代处理的文件.
int printf(const char *format, ...)
int fprintf(FILE *stream, const char *format, ...)
int scanf(const char *format, ...)
int fscanf(FILE *stream, const char *format, ...)
由函数声明中可以看出,fprintf()和fscanf()与printf()和scanf()的使用方式类似,只不过fprintf()和fscanf()与与printf()和scanf()相比,把FILE指针作为第一个参数.
通过对比我们可以得出:
scanf | printf | 应用于标准输入流和输出流的格式化输入输出语句 |
---|---|---|
fscanf | sprintf | 应用于所有的标准输入流和输出流的格式化输入输出语句 |
sscanf | sprintf | 可以把结构化的数据转化为字符串,也可以从字符串中提取结构化的数据 |
3.缓冲区刷新 fflush()函数
int fflush()函数
int fflush(FILE *stream)
调用fflush()函数会使得输出缓冲区中所有未写入的数据被发送到fp指定的输出文件中,这个过程称为刷新缓冲区.如果fp是空指针,所有的输出缓冲区都被刷新.如果成功,返回值为0,如果发生错误,则返回EOF.
4.feof()和ferror()函数
注:在文件读取过程中,不能用feof函数的返回值来直接判断文件的是否结束,而是应用于当文件读取结束时,判断是读取失败结束,还是遇到文件尾结束.feof()和ferror()函数就是用于区分这两种情况,
当上一次输入调用检测到文件结束时,feof()函数返回一个非零值,否则返回零.当读或写出现错误时,ferre()函数返回一个非零值,否则返回零.
例如:
int main()
{
FILE*pf = fopen("data.txt", "r");
if (pf == NULL)
{
printf("文件打开失败!\n");
return 1;
}
//读取
int ch = 0;
while ((ch = fgetc(pf)) != EOF)
{
printf("%c ", ch);
}
//找结束的原因
if (ferror(pf))
{
printf("读取是发生错误,失败,而结束\n");
}
else if (feof(pf))
{
printf("遇到文件末尾,而结束的\n");
}
fclose(pf);
pf = NULL;
return 0;
}
3.文件关闭
在文件读写完毕后,一定要使用fclose( )函数关闭文件,必要时刷新缓冲区。
int fclose(FILE *stream);//关闭流stream并刷新所有的缓冲区;
- stream : 这是指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流
- 返回值:如果流成功关闭,则该方法返回零。如果失败,则返回 EOF。
在编写程序中,应该检查是否成功关闭文件,如果成功关闭,fclose()返回0,否则返回EOF;(如果磁盘已满、移动硬盘被移除或出现I/O错误,都会导致fclose()函数失败;
if(fclose(fp) != 0)
{
printf("Error in closing file!");
}
总结
文件操作过程中一定要遵循一定的顺序,否则就会出现错误或者文件信息丢失的情况;
1. 打开文件
打开文件后对其进行判断,看是否打开成功,打开成功后方可对其进行操作
FILE * fp = fopen ("test.txt", "w+"); //1、打开文件
if (pf == NULL) //判断文件是否打开成功
{
printf("文件打开失败!");
return 1;
}
2. 文件操作
文件打开成功后,方可根据需求,运用相应的函数对文件进行操作
3. 关闭文件
在文件读写之前应该先打开文件,在使用结束之后应该关闭文件:
int main()
{
FILE * fp = fopen ("test.txt", "w+"); //1、打开文件
if(fclose(fp) != 0) //判断文件是否打开成功
{
printf("Error in closing file!");
}
fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014); //2、文件读写
if(fp != NULL) //3、关闭文件,判断是否关闭成功
{
fclose(fp);
if(fclose(fp) != 0)
{
printf("Error in closing file!");
return 1;
}
fp = NULL;
}
return 0;
}