1.文件的打开与关闭:
运用到关键字:fopen和fclose,还有文件指针(eg:FILE* pf)
文件指针:用来存储该文件的一个地址,通过该指针可以找到该文件,是用来操作与维护流的
打开时需用fopen是需要判断文件是否打开成功,否则一旦没有打开成功会出现会空指针异常(文件打开失败,返回NULL),并且该文件必须在该目录下被创建,否则是一定会出现空指针异常的。
关闭时需将创建的文件指针进行置为NULL的操作(否则会出现野指针)。
例如:
int main()
{
//这里表示对文件进行写的操作,还可以进行的只读的的操作
FILE* pf1 = fopen("test.txt", "w");
//如果pf1为空的话,表示打开test.txt文件失败
if(pf1 == NULL)
{
perror("fopen");
return 1;
}
//写文件
//此处省略
//关闭文件
fclose(pf1);
pf1 = NULL;
return 0;
}
(1)文件打开时的基础操作:
2.文件标准流
stdin ——标准输入流
stdout ——标准输出流
stderr ——标准错误流
c程序在启动是就会默认打开这三个流。可以直接使用printf,scanf进行输入输出操作
3.文件的顺序读写函数:
(1)fpetc与fgutc
返回类型为int,当读取或写入失败时,会返回EOF。
1)fputc:int fputc(int chracter,FILE* stream)
将一个字符(注意该字符是用ASCII码值存储的,得用int类型来存储)写入到stream所指向的文件流中去,它是字符输出函数 => 所有输出流
eg:
#include <stdlib.h>
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件:写入abcd
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fputc('d', pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
2)fgetc:int fgetc(FLIE* stream)
读取文件的一个文件的第一个字符,如果返回值不为EOF,则可以继续读取直到读取失败返回EOF,它是字符输入函数 => 所有输入流
eg:
#include <stdio.h>
//此时test.txt文件中已写入abcd
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "r");
if(pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
int ch = 0;
while((ch = fgetc()) != EOF)
{
printf("%c ", ch); //打印a b c d
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
(2)fputs与fgets
1)fputs:int fputs(const char* str, FILE* stream)
将一个字符串写入到stream文件流中去,它是文本行输出函数 => 所有输出流
eg:
//假设已清空test.txt文件中的所有内容
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
fputs("blackpink", pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
2)fgets:char* fgets(char* str, int num, FILE* stream)
将文件中从开始位置向后num个字符数读取到str中,它是文本行输入函数 => 所有输入流
eg:
#include <stdio.h>
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
char arr1[50] = "****************************************";
fgets(arr1, 5, pf);
printf("%s\n", arr1); //black
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
(3)fprintf与fscanf:
1)fprintf:int fprintf(FILE* stream, const char* format)
向stream文件流中格式化写入一定的数据,它是格式化输出函数 => 所有输出流
eg:
#include <stdio.h>
//假设已清空
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
fprintf("%s %d %l", "zhangsan", 20, 95.4f);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
2)fscanf:int fscanf(FILE* stream, const char* format)
从stream文件流中格式化读取一定的数据,它是格式化输入函数 => 所有输入流
eg:
#include <stdio.h>
struct Stu
{
char name[20];
int age;
float grade;
}s;
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
fscanf(FILE* pf, "%s %d %f", s.name, s.age, s.grade);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
(4)fwrite与fread:
由于返回值类型为size_t,则看是否读写成功,看返回值大小是否ptr所向的数组的大小
size_t size:每个元素的字节大小
size_ count:元素个数
1)fwrite:size_t fwrite(const void* ptr, size_t size, size_t num, FILE* stream)
它是二进制输出函数 => 文本输出流
eg:
#include <stdio.h>
//假设已清空
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "bw");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
char buf[] = "blackpink";
fwrite(buf, sizeof(char), 9, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
2)fread:size_t fread(void* ptr, size_t size, size_t num, FILE* stream)
它是二进制输入函数 => 文本输入流
eg:
#include <stdio.h>
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "br");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
char ret[] = "0";
fread(ret, sizeof(char), 9, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
4.文件的随机访问函数
(1)feek:int feek(FILE* stream, int offset, int origin)
根据文件指针的位置与偏移量来定位文件指针。
关于origin:有三种情况:SEEK_CUR(文件指针当前位置),SEEK_END(文件末尾位置),SEEK_SET(文件开头位置)
eg:
#include <stdio.h>
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
//文件开头向后5个位置
fseek(pf, 5, SEEK_SET);
//从第六个元素开始替换后面四个元素为rose
fputs("rose", pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
(2)ftell:long int ftell(FILE* stream)
返回文件指针相对于起始位置的偏移量
eg:
#include <stdio.h>
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
//文件开头向后5个位置
fseek(pf, 5, SEEK_SET);
//从第六个元素开始替换后面四个元素为rose
fputs("rose", pf);
int ret = ftell(pf);
printf("%d", ret); // 9
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
(3)rewind:void rewind(FILE* stream)
让当前文件指针回到文件的起始位置
5.文件结束的标志
feof:int feof(FILE* stream)
判断一个文件的读取是否是在文件末尾才结束,还是其他问题(往往中途不会出错,一般是开头就直接出错,用ferror进行判断)
eg:
#include <stdio.h>
//现在文件的内容:text.txt:blackrose
int main()
{
//打开文件
FILE* pf = fopen("text.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
int ch = 0;
while((ch = fgetc(pf)) != EOF)
{
printf("%c", ch); // blackrose
}
//判断是否读取到文件末尾
if((ch = fgetc(pf)) == EOF)
{
if(feof(pf))
{
printf("文件读取到末尾");
}
else if(ferror(pf))
{
printf("文件为读取到末尾,是有其他错误");
perror("ferror");
}
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}