目的:为使得信息得以保留,需要用到文件。通过把信息记录到文件中,调用或者修改来使得信息的更新。
文件:存储在硬盘的文件
1.文件的种类程序文件:源文件,目标文件,可执行文件
数据文件:数据存储在文件中,程序需要实现在中输入和输出的对象
2. 操作文件 1)文件的打开读写的判定是根据内存为主体的行为:
写(输出):内存对文件进行操作写入数据
读(输入):内存对文件的数据进行读取
fopen();
FILE *fopen( const char *filename, const char *mode );
FILE*:是文件信息区的地址,即文件指针
其实一个文件的与程序连接是需要一定的描述,当一个文件被开辟空间(文件信息区)到内存中是通过一个结构体来描述的,这个结构体的成员有文件名,文件的地址等等信息。该结构体记录到内存中即和文件有了联系,而后返回的文件指针FILE*就是为了让用户对文件进行操作;
const char* filename:文件名
const char *mode:打开方式 -------r(读)写(w)追加(a)
"r":若读取失败返回空指针NULL;
所以进行操作前一定要判断是否为NULL;
int main()
{
FILE* p = fopen("test.txt", "a");
if (p == NULL)
{
perror("fopen");
return 1;
}
return 0;
}
"w"和"a":若读取失败会新建一个文件如何返回地址;2)文件的关闭
文件操作完毕需要对文件进行关闭
int fclose( FILE *stream );
只需要传入文件指针,当关闭文件后需要对指针设置为NULL
fclose(p); p=NULL;3)读写文件的具体操作
打开文件操作对应的读写操作与后面的读写形式一致
1.fputc()和fgetc()
//fputc()
int main()
{
FILE* p = fopen("test.txt", "w");
if (p == NULL)
{
perror("fopen");
return 1;
}
//fputc('a', p);
for (char i = 'a'; i <= 'z'; i++)
{
fputc(i, p);
}
fclose(p);
p = NULL;
return 0;
}
//int fputc( int c, FILE *stream );
//输入参数:需要输出的字符,文件指针
//fgetc()
int main()
{
FILE* p = fopen("test.txt", "r");
if (p == NULL)
{
perror("fopen");
return 1;
}
char ch = 0;
while ((ch = fgetc(p)) != EOF)
{
printf("%c", ch);
}
fclose(p);
p = NULL;
return 0;
}
//int fgetc( FILE *stream );
//输出参数:文件指针
//输入参数:如果指针走到的地方再也没有信息时,输出EOF
//EOF表示读取结束
2.fputs()和fgets ()
//fputs()
int main()
{
FILE* p = fopen("test.txt", "w");
if (p == NULL)
{
perror("fopen");
return 1;
}
fputs("abcd", p);
fclose(p);
p = NULL;
return 0;
}
//int fputs( const char *string, FILE *stream );
//输入参数:需要的字符串,文件指针
//fgets()
int main()
{
FILE* p = fopen("test.txt", "r");
if (p == NULL)
{
perror("fopen");
return 1;
}
char arr[20];
fgets(arr, 3, p);
printf("%s", arr);
fclose(p);
p = NULL;
return 0;
}
//char *fgets( char *string, int n, FILE *stream );
//输入参数:承载文本的字符串的变量,多少个字符串(特别注意,最后一位是传入' '),文件指针
//输出参数:文件指针所停留的位置
//输出的参数指针为NULL时,说明读取结束,后面再无内容
3)fscanf和fprintf
该函数针对格式化数据
前几组只能对字符或者字符串进行,这俩个函数针对所有类型
struct Stu
{
char arr[20];
int a;
float score;
};
int main()
{
struct Stu s = { "zhangsan",25,50.5f };
FILE* p = fopen("test.txt", "w");
if (p == NULL)
{
perror("fopen");
return 1;
}
fprintf(p, "%c %d %f", s.arr, s.a, s.score);
fclose(p);
p = NULL;
}
//和printf的形式差不多,前面多一个文件指针;
struct Stu
{
char arr[20];
int a;
float score;
};
int main()
{
FILE* p = fopen("test.txt", "r");
if (p == NULL)
{
perror("fopen");
return 1;
}
struct Stu s = { 0 };
fscanf(p, "%s %d %f", s.arr, &(s.a), &(s.score));
printf("%s %d %f", s.arr, s.a, s.score);
fclose(p);
p = NULL;
return 0;
}
都需要结构体变量来接收数据。
4)fread和fwrite
struct Stu
{
char arr[20];
int a;
float score;
};
int main()
{
FILE* p = ("text.txt", "wb");
if (p == NULL)
{
perror("fopen");
return 1;
}
struct Stu s = { "zhangsan",25,50.5f };
fwrite(&s, sizeof(struct Stu), 1, p);
fclose(p);
p = NULL;
return 0;
}
struct Stu
{
char arr[20];
int a;
float score;
};
int main()
{
FILE* p = ("text.txt", "rb");
if (p == NULL)
{
perror("fopen");
return 1;
}
struct Stu s = { 0 };
fread(&s, sizeof(struct Stu), 1, p);
printf("%s %d %f", s.arr, s.a, s.score);
fclose(p);
p = NULL;
return 0;
}
//fread的输出参数为实际读取的数目,如果数目小于本身要读取的数则说明读取结束
5)区分
scanf / fscanf / sscanf
printf / fprintf / sprintf
scanf:针对标准输入流的格式化输入语句——stdin(键盘)
printf:针对标准输出流是格式化输出语句——stdout(屏幕)
fscanf:针对所有流的格式化输入语句
fprintf:针对所有流的格式化输出语句
sscanf:一个字符串转化为格式化数据
sprintf:格式化数据转化为一个字符串



