本文是小编巩固自身而作,如有错误,欢迎指出!
1.使用文件的原因
我们编写的程序都是有生命周期的,储存在电脑的内存中,如果程序退出,内存回收,数据就会丢失,等程序再次运行,是看不到之前的数据的,如果想要将其保存起来,我们就需要用到文件。
2.什么是文件
磁盘(硬盘)上的⽂件是⽂件。 但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类的)。
2.1程序文件
程序文件其实就是我们平时了解的
源程序文件(.c)
目标文件(.obj)
可执行程序(.exe)
2.2数据文件
⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或 者输出内容的⽂件。
本章讨论的是数据⽂件。 在以前各章所处理数据的输⼊输出都是以终端为对象的,即从终端的键盘输⼊数据,运⾏结果显⽰到 显⽰器上。3
其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使⽤,这⾥处 理的就是磁盘上⽂件。
3.二进制文件和文本文件
根据数据的组织形式,数据⽂件被称为⽂本⽂件和⼆进制⽂件。
数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存的⽂件中,就是⼆进制⽂件。 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂ 本⽂件。
⼀个数据在⽂件中是怎么存储的呢?
字符⼀律以ASCII形式存储,数值型数据既可以⽤ASCII形式存储,也可以使⽤⼆进制形式存储。
看看如下代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 10000;
FILE* pf = fopen("testblog.txt", "wb");//以二进制写文件
fwrite(&a, 4, 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
下面是打开二进制文件的方法
打开后我们可以看到
4.文件的打开与关闭
4.1流与标准流
流是一个很抽象的概念,简单的白话来说就是数据的输入与输出都要通过流,直接解释很难理解,我们可以通过一些标准流辅助理解
为什么我们从键盘输⼊数据,向屏幕上输出数据,并没有打开流呢?
那是因为C语⾔程序在启动的时候,默认打开了3个流:
• stdin标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。
• stdout标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出 流中。
• stderr标准错误流,⼤多数环境中输出到显⽰器界⾯。
这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。 stdin、stdout、stderr三个流的类型是: FILE * ,通常称为⽂件指针。 C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。
4.2文件打开关闭函数
⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件。
在编写程序的时候,在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了 指针和⽂件的关系。
ANSIC规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件。
下面是函数原型
//打开⽂件
FILE * fopen ( const char * filename, const char * mode );
//关闭⽂件
int fclose ( FILE * stream );//成功返回0,失败返回EOF
下面是文件的打开模式
5.文件的读写
5.1顺序读写函数介绍
5.1.1fgetc,fputc
fgetc
函数从给定的文件流 stream
中读取一个字符,并将文件位置指示器向前移动一个字节(如果文件流支持定位操作)。
fputc
是 C 语言标准库中的一个函数,用于将一个字符写入到指定的文件流中。
函数原型
int fgetc(FILE *stream);
int fputc(int character, FILE *stream);
下面是示例
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "w+");
if (file == NULL) {
perror("无法打开文件");
return 1;
}
char ch = 'A';
fputc(ch, file);
// 将文件指针移动到文件开头
rewind(file);
char ans;
ans = fgetc(file);
// 使用 %c 格式化字符输出
printf("%c\n", ans);
fclose(file);
return 0;
}
5.1.2fgets,fputs
fgets
是 C 语言标准库中的一个函数,用于从指定的文件流中读取一行数据。
fputs
是 C 语言标准库中的一个函数,用于将一个字符串写入到指定的文件流中。
函数原型
char *fgets(char *str, int num, FILE *stream);
int fputs(const char *str, FILE *stream);
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "w");
if (file == NULL) {
perror("无法打开文件");
return 1;
}
const char* message = "这是要写入文件的内.";
if (fputs(message, file) == EOF) {
perror("写入文件失败");
fclose(file);
return 1;
}
fclose(file); // 先关闭文件,以确保写入操作完成并刷新缓冲区
file = fopen("example.txt", "r"); // 重新以读模式打开文件
if (file == NULL) {
perror("无法打开文件");
return 1;
}
char ans[100];
if (fgets(ans, 20, file) != NULL) {
for (int i = 0; ans[i] != '\0'; i++) { // 正确的循环条件,确保只输出实际读取到的字符
printf("%c", ans[i]);
}
}
else {
perror("读取文件失败");
}
fclose(file);
return 0;
}
5.1.3fprintf,fscanf
fscanf
和 fprintf
是 C 语言中用于格式化输入输出的函数,它们操作的对象是文件流。
函数原型
int fprintf(FILE *stream, const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
#include <stdio.h>
int main()
{
// 以读写模式打开文件
FILE *file = fopen("data.txt", "w+");
if (file == NULL) {
perror("无法打开文件");
return 1;
}
// 使用 fprintf 写入数据
int num = 42;
float fnum = 3.14f;
const char *str = "Hello, World!";
int writtenChars = fprintf(file, "%d %f %s", num, fnum, str);
if (writtenChars < 0)
{
perror("写入文件失败");
fclose(file);
return 1;
}
// 将文件指针重置到文件开头,以便读取
rewind(file);
// 使用 fscanf 读取数据
int readNum;
float readFnum;
char readStr[100];
int readItems = fscanf(file, "%d %f %s", &readNum, &readFnum, readStr);
if (readItems == EOF)
{
perror("读取文件失败");
fclose(file);
return 1;
}
// 输出读取的数据
printf("读取的整数: %d\n", readNum);
printf("读取的浮点数: %f\n", readFnum);
printf("读取的字符串: %s\n", readStr);
fclose(file);
return 0;
}
6.文件的随机读写
6.1fseek
根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)。
int fseek ( FILE * stream, long int offset, int origin );
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ( "example.txt" , "wb" );
fputs ( "This is an apple." , pFile );
fseek ( pFile , 9 , SEEK_SET );//SEEK_SET是起始位置
fputs ( " sam" , pFile );
fclose ( pFile );
return 0;
}
6.2 ftell
返回⽂件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
#include <stdio.h>
int main()
{
FILE* pFile;
long size;
pFile = fopen("myfile.txt", "wb+");
if (pFile == NULL)
perror("Error opening file");
else
{
fseek(pFile, 0, SEEK_END); // non-portable
size = ftell(pFile);
fclose(pFile);
printf("Size of myfile.txt: %ld bytes.\n", size);
}
return 0;
}
6.3rewind
在先前的代码中已经使用过了,其作用是让⽂件指针的位置回到⽂件的起始位置,不再演示
7.文件结束的判定
7.1feof
feof
是 C 语言标准库中的一个函数,用于检测文件指针是否已到达文件末尾。
牢记:在⽂件读取过程中,不能⽤ feof 函数的返回值直接来判断⽂件的是否结束。 feof 的作⽤是:当⽂件读取结束的时候,判断读取结束的原因是否是:遇到⽂件尾结束。
如果文件指针已经到达文件末尾,或者在读取操作中遇到了文件末尾的条件,feof
函数将返回一个非零值(表示真);否则,返回 0
(表示假)。
函数原型
int feof(FILE *stream);
#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
perror("无法打开文件");
return 1;
}
int ch;
while (!feof(file)) {
ch = fgetc(file);
if (ch != EOF) {
putchar(ch);
}
}
if (feof(file)) {
printf("\n已到达文件末尾\n");
} else {
printf("\n读取文件时发生错误\n");
}
fclose(file);
return 0;
}
今天的分享就到这里,后续会继续更新,感谢阅读!