首页 >> 大全

初识 C语言文件操作

2023-12-23 大全 28 作者:考证青年

这些信息是保存在一个结构体变量中。该结构体类型是由系统声明的,取名为FILE。

每当打开一个文件时,系统就会根据文件情况自动创建一个FILE结构的变量,并填充其中的信息。

struct _iobuf {char *_ptr;int   _cnt;char *_base;int   _flag;int   _file;int   _charbuf;int   _bufsiz;char *_tmpfname;};
typedef struct _iobuf FILE;

所以我们一般通过文件指针变量找到与它相关联的文件

FILE* pf;//文件指针变量

流程:

我们在程序中实现文件打开和关闭,一般按照三步骤:

打开文件 读/写文件 关闭文件

我们在打开文件时,又不得不引入如下的函数:

FIEL* fopen(const char* filename, const char* mode)

其中的参数

————文件名。

mode—————打开方式。

以下是打开方式的各个操作符:

下面就是使用文件的三步骤例子:

#include 
int main ()
{FILE * pFile;//打开文件pFile = fopen ("myfile.txt","w");//文件操作if (pFile!=NULL){fputs ("fopen example",pFile);//关闭文件fclose (pFile);}return 0;
}

文件路径:

文件路径指定到文件或文件夹的位置的描述。它是由一系列文件夹的名称、符号和文件名组成的。在操作系统中,文件路径可以是绝对路径或相对路径。

相对路径:指定文件或文件夹的位置相对于当前工作目录。例如:

在指定路径时,可以使用一些特殊符号来描述路径。如:

文件的顺序读写:

文件的顺序读写是指按照文件中数据的顺序依次读取或写入数据。在进行文件读写时,操作系统会维护一个文件指针,用于指示当前读写的位置。初始时,文件指针指向文件的开头。

顺序读写的过程如下:

打开文件,获取文件句柄。

从文件句柄中读取数据,操作系统会自动将文件指针指向下一个数据的位置。

继续读取数据,直到读取到文件末尾。

顺序写入的过程如下:

打开文件,获取文件句柄。

向文件句柄中写入数据,操作系统会自动将文件指针指向下一个数据的位置。

继续写入数据,直到写入完所有数据。

顺序读写可以提高文件读写的效率,因为每次读写时都能够连续地访问相邻的数据,避免了频繁地寻找数据的过程。

接下来我们就来实现文件的读写

首先我们来认识几个函数:

实现字符输入输出: fputc:

fgetc是C语言中的标准输入输出库函数,用于从指定的文件指针中读取一个字符。其原型为:

int fputc(int character, FILE *stream);

#define _CRT_SECURE_NO_WARNINGS  1
#include int main() {FILE* pf = fopen("test.txt", "w");if (pf == NULL) {perror("fopen");return 1;}//写文件char ch = 0;for (ch = 'a'; ch <= 'Z'; ch++){fputc(ch, pf);}fclose(pf);pf = NULL;return 0;
}

上述代码会读取名为"test.txt"的文件中的所有内容,并将26个英文字母存放在文件“test.txt”中。

此时我们到当前程序的目录底下就会发现:

此时该文件就存放了a——z这26个字母。

fgetc:

fgetc是C语言中的标准输入输出库函数,用于从指定的文件指针中读取一个字符。其原型为:

int fgetc(FILE *stream);

其中,为指向文件的指针。函数返回值为读取的字符的ASCII码值,如果已经到达文件末尾,则返回EOF。

使用fgetc可以逐个字符地读取文件,例如:

#include int main() {FILE *fp;int c;fp = fopen("test.txt", "r");if (fp == NULL) {printf("Failed to open the file.\n");return 1;}while ((c = fgetc(fp)) != EOF) {putchar(c);}fclose(fp);return 0;
}

上述代码会读取名为"test.txt"的文件中的所有内容,并输出到标准输出。

在这两个函数中,我们多次提到“流”这个概念,接下来我们就来介绍介绍“流”。

“流”

“流”是一个高度抽象的概念!目前我们可以理解为“中转站”。

流()通常是指某个持续的、连续的、有序的数据序列,可以是数据源(例如文件、网络连接等)中的数据流,也可以是程序中的内存流(例如输入输出流、网络流等)。流的概念主要用于表示处理数据的可迭代性,它使得程序能够在处理数据的同时,将数据逐个读取或写入,而不需要一次性读取或写入整个数据集,从而大大提高了程序的效率和可扩展性。流可以分为输入流和输出流,输入流用于从数据源读取数据,输出流用于向目标输出数据。流也可以通过缓存机制来提高读写性能,即先将数据先读取到缓存中,再从缓存中进行读写操作。

我们对于刚刚讲的函数中,我们可以总结出如图:

我们也可以利用我们学过的知识来解释:

只要C语言程序运行起来,就默认打开了3个流:

1.标准输入流——stdin

2.标准输出流——

3.标准错误流——

实现文本行输入输出: fputs:

fputs是一个C标准库函数,用于将字符串写入文件中。它的原型为:

int fputs(const char *str, FILE *stream);

其中,str是待写入的字符串,是目标文件指针。

c语言操作文件步骤是什么_c语言文件操作的步骤是哪几步_

函数会将字符串写入文件中,并返回一个非负整数表示操作成功。如果出现错误,函数会返回EOF。与puts函数不同的是,fputs不会在字符串末尾加上一个换行符。如果需要换行符,需要手动在字符串中添加一个"\n"字符。

fgets:

fgets()是C编程语言中的一个函数,用于从文件或控制台输入中读取字符串。它是C中标准输入/输出库(stdio.h)的一部分,通常用于从控制台中读取用户的输入。

fgets()函数的语法是:

char *fgets(char *str, int n, FILE *stream);

str是指向存储字符串的字符数组的指针。

n是要读取的最大字符数。

是指向要读取的文件或stdin(标准输入)的指针。

该函数最多从流所指向的文件中读取n-1个字符,直到遇到文件结束符(EOF)或换行符。生成的字符串存储在str所指向的缓冲区中,并在字符串末尾添加一个空字符\0。

fgets()在成功时返回相同的缓冲区str,在错误时或在读取任何字符之前到达文件结束时返回NULL。

例:

int main()
{FILE* pf = fopen("test.txt", "r");char arr[100] = { 0 };fgets(arr, 100, pf);printf("%s\n", arr);fclose(pf);pf = NULL;return 0;
}

运行结果如图:

若我们在文件中写:

两行数据,此时输出结果为:

这更好的说明了fgets一次只能读取一行。

实现格式化输入输出函数: :

是C编程语言中的一个函数,用于将格式化的输出输出到文件流或控制台。它允许程序员以特定的方式输出格式化的数据,如字符串、数字和其他变量。该函数接受一个格式字符串作为其第一个参数,后跟一个参数列表,这些参数对应于格式字符串中的格式说明符。格式字符串包含要打印的值的占位符,格式字符串后面的参数提供要打印的相应值。下面是一个如何使用函数的示例:

int main() {FILE *fp;fp = fopen("test.txt", "w"); // 打开文件int num1 = 10, num2 = 20;float pi = 3.14;// 写文件fprintf(fp, "num1 = %d, num2 = %d\n", num1, num2);fprintf(fp, "pi = %f\n", pi);fclose(fp); // 关闭文件fp = NULL;return 0;
}

在本例中,函数用于将格式化的输出写入文件流。格式字符串包含变量num1、num2和pi值的占位符,它们作为函数的参数提供。输出被写入由file指针fp指定的文件。函数还用于将格式化的输出写入控制台。输出类似于写入文件的输出。最后,使用关闭文件。

文件如图所示:

()是一个C库函数,用于从文件或输入流中读取数据。它类似于标准输入函数scanf(),但它不是从标准输入读取,而是从指定的文件流读取。

()的语法是:

int fscanf(FILE *stream, const char *format, ...)

第一个参数是要读取的文件流,第二个参数是指定预期输入格式的字符串,其余参数是指向将接收输入值的变量的指针。

例如,下面的代码从一个名为"test.txt"的文件中读取文件中的数值,并打印到屏幕上:

int main() {FILE *fp;fp = fopen("test.txt", "r"); // 打开文件//读文件fscanf(fp, "num1 = %d, num2 = %d\n", &num1, &num2);fscanf(fp, "pi = %f\n", &pi);printf("num1 = %d, num2 = %d\n", num1, num2);printf("pi = %f\n", pi);fclose(fp); // 关闭文件fp = NULL;return 0;
}

请注意,与scanf()一样,()返回成功匹配和分配的输入项数,可用于错误检查。

二进制的输入输出: :

是C编程语言中的一个函数,用于将数据块写入文件。它有四个参数:指向要写入的数据的指针、要写入的每个元素的大小、要写入的元素的数量,以及指向要写入的文件的指针。

下面是一个使用将整数写入文件的示例:

#include int main() {int num = 42;//打开文件FILE *file = fopen("file.bin", "wb");//写文件fwrite(&num, sizeof(int), 1, file);//关闭文件fclose(file);file = NULL;return 0;
}

在本例中,整数num被写入名为file.bin的二进制文件中。调用函数时带有一个指向num的指针、一个整数的大小((int))、要写入的整数的数量(在本例中为1)和一个指向文件的指针。最后,使用关闭文件。

此时文件中的数据为:

fread:

fread是一个C库函数,用于将二进制数据从文件读入缓冲区。它接受四个参数:

指向将存储数据的缓冲区的指针。

要读取的一个元素的大小。

要读取的元素数目。

要读取的文件的文件指针。

函数返回从文件中成功读取的元素总数。

例:

int main() {int num = 42;int arr[10] = { 0 };//打开文件FILE *file = fopen("file.txt", "rb");//写文件//fwrite(&num, sizeof(int), 1, file);//读文件fread(arr, sizeof(int), 1, file);printf("%d\n", arr[0]);//关闭文件fclose(file);file = NULL;return 0;
}

输出结果为:

文件的随机读写: fseek:根据文件指针的位置和偏移量来定位文件指针

fseek函数是C标准库中的一个函数,用于设置文件指针的位置。其函数原型为:

int fseek(FILE *stream, long offset, int whence);

其中,是指向文件的指针,是偏移量,指示偏移量相对位置,它的取值及含义如下:

fseek函数返回0表示成功,非0值表示出错。

使用fseek函数可以对文件进行定位,从而读写文件的指定位置。

例子:

#include 
int main ()
{FILE * pFile;pFile = fopen ( "example.txt" , "wb" );fputs ( "This is an apple." , pFile );fseek ( pFile , 9 , SEEK_SET );fputs ( " sam" , pFile );fclose ( pFile );return 0;
}

文件内容为:

ftell:返回文件指针相对于起始位置的偏移量

ftell函数是一个C标准库函数,用于获取当前文件流(FILE对象)的当前文件位置指针的位置。该函数的原型为:

long int ftell(FILE *stream);

其中,为文件流指针,表示当前要进行操作的文件流。ftell函数的返回值为当前文件位置指针的位置,类型为long int。

_c语言文件操作的步骤是哪几步_c语言操作文件步骤是什么

ftell函数主要用于二进制文件的读写操作中。在进行读写操作前,我们需要先打开一个文件流并设置当前文件位置指针的位置。读写操作完成后,我们需要获取当前文件位置指针的位置,以便下次操作。

例如:

FILE* fp = fopen("test.bin", "rb");
if (fp != NULL) {fseek(fp, 0, SEEK_END);  // 将文件位置指针设置到文件末尾long int file_size = ftell(fp);  // 获取文件大小...fclose(fp);
}

在上述代码中,我们打开了一个二进制文件test.bin,将文件位置指针设置到文件末尾,然后使用ftell函数获取了文件大小。最后关闭了文件流。

:让文件指针的位置回到起始位置

() 是一个标准 C 库函数,可以将文件指针指向文件的开头。它的原型为:

void rewind(FILE *stream);

() 函数将文件位置指针指向文件开头,这意味着接下来的所有读取操作将从文件开始处开始。 它不会关闭文件,也不会清除错误标志或重置文件模式。() 函数主要用于需要多次读取文件的情况,例如读取二进制文件,可以使用它来回到文件的开头位置。

scanf/的理解

scanf是格式化的输入函数,针对的是标准输入流(键盘)

是格式化的输出函数,针对的是标准输出流(屏幕)

scanf和是针对标准输入/输出流的格式化输入/输出函数

/的理解

是针对所以输入流(文件流,输入流)的格式化输入函数

是针对所以输出流(文件流,输出流)的格式化输出函数

/的理解

是将字符串转换成格式化的数据

是将格式化的数据转化成字符串

文本文件和二进制文件

数据在内存中以二级制的形式存储,如果不加转换的输出到外村,就是二进制文件。

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

一个数据在内存中是怎么存储的呢? 字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。 如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而 二进制形式输出,则在磁盘上只占4个字节(测试)。

例子:

int main()
{int a = 10000;FILE* pf = fopen("test.txt", "wb");fwrite(&a, 4, 1, pf);//二进制的形式写到文件中fclose(pf);pf = NULL;return 0;
}

写完文件后将文件拖动到VS中

并且以二进制的方式打开:

得到结果 10 27 00 00

又因为机器是小端存储,则可以理解为:

所以才会输出:

文件的读取结束和判定 被错误使用的feof:

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。 而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets ) 例如: fgetc 判断是否为 EOF . fgets 判断返回值是否为 NULL .

2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。 例如: fread判断返回值是否小于实际要读的个数。

fgetc判断是否为EOF

fgets判断返回值是否为NULL

fread要求读取count个大小为size字节的数据

如果真的读取到了count,返回count。

如果小于则返回真是读到了的个数。

例子:

《完成文件的拷贝》

int main()
{FILE* pfread = fopen("data1.txt", "r");if (pfread == NULL){perror("fopen");return 1;}FILE* pfwrite = fopen("data2.txt", "w");if (pfwrite == NULL){perror("fopen");fclose(pfread);pfread = NULL;return 1;}int ch = 0;while ((ch = fgetc(pfread)) != EOF){fputc(ch, pfwrite);}fclose(pfread);pfread = NULL;fclose(pfwrite);pfwrite = NULL;return 0;
}

我们在执行代码之前,先编写一个data1.txt的文件,里面写上abcd

此时执行代码

打开data2.txt

代码执行成功!

文件缓冲区

文件缓冲区是指在处理文件时系统为文件I/O操作所分配的一段内存空间。当我们打开一个文件并执行读写操作时,操作系统会将文件的一部分或全部内容读入文件缓冲区中进行处理,因为读写操作比较耗时,通过文件缓冲区可以提高文件I/O操作的效率。当我们完成读写操作后,系统将缓冲区中的数据写回到磁盘中。因此,文件缓冲区可以有效地减少磁盘I/O操作的次数,从而提高系统的性能。

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序 中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装 满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓 冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根 据C编译系统决定的。

正因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在程序结束时主动关闭文件。

总结:

本文我们介绍了C语言实现文件操作,我们在此讲解了很多函数,希望大家在看完文章后可以动手尝试编写编写代码,自己建立再销毁一个文件,并对其中的内容进行修改和增加达到自定义程度。

刚开始会对这些函数产生疑惑甚至混淆概念。但只要每天动手尝试尝试编写函数实现文件的操作,相信很快就会上手这些函数。

记住!“坐而言不如起而行!”

speak than words!

本章代码可以访问我的Gitee仓库:: 本仓库里的代码为c语言的测试代码 -

接下来我们会利用文件修改通讯录。

可以再复习以下关于通讯录的创建

blog如下:

运用动态内存实现通讯录(增删查改+排序)-CSDN博客

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了