文件对大家来说很熟悉,常见的有txt文本文档,办公用的word文档等,主要作用就是保存数据
在C语言中,文件时计算机领域的一个重要概念,通常指存储在外部介质上数据的集合。操作系统以文件为单位对数据进行管理,以文件名访问文件。
按文件内容划分源文件、目标文件、数据文件等
C语言源程序文件的扩展名为.c,C语言的源文件经过编译,产生扩展名为.exe可执行文件,最后C语言的文件操作函数会把程序运行的结果存储到文件中,得到一个数据文件。
例如大家在Dev C++编写一段输出“你好C语言”的的代码,经过编译和运行,会在命令行窗口输出结果,同时也可以在电脑上文件资源管理器上查看你自已保存的文件地址,就是数据文件
按组织形式划分文本文件和二进制文件
文本文件指文件的内容由ASCII码组成,一个字符占用1字节,主要用于存储和传输文本数据,如文本文档、程序代码等,具有易于处理和读取,但存储效率较低,因为每个字符都需要占用一个字节的存储空间。
二进制文件由0和1组成,是以数据在内存中的存储形式原样输出到磁盘上所产生的文件,具有输入输出速度快,节省内存空间的优势,但可阅读性低
在C语言中,文件的基本操作分三个步骤,即打开文件、读取数据和关闭文件
利用程序在打开文件时,首先在内存中为输入、输出数据开辟缓冲区;
向数据文件中写入数据时,先将数据送入文件缓冲区,当文件缓冲区写满时,在一起写到外存;
数据文件的读取数据也是一样,不过顺序相反。
如果缓冲区不满时结束操作,数据会丢失,但如果关闭文件,不管是否写满,都会把缓冲区数据
存入外存,保证数据不丢失。
不打开文件无法读取文件数据,不关闭文件会浪费操作系统资源,导致数据丢失。
在C语言中,把指向一个文件的指针称为文件指针,通过文件指针可以对它所指的文件进行操作。
定义文件类型的指针一般格式为
FILE *指针变量标识符;
FILE 为大写,是系统定义的一个结构,该结构中含有文件名,文件状态和文件当前位置信息,
*指针变量标识符是FILE指向的目的文件,可以是指针的变量
调用fopen()函数一般形式:
- FILE *p;
- p=fopen(文件名, 文件使用模式);
文件使用模式的格式如下:
| 模式 | 描述 |
|---|---|
| r | 打开文件用于读取。如果文件不存在,则返回 NULL。 |
| w | 打开文件用于写入。如果文件不存在,则创建该文件;如果文件已存在,则清空文件内容。 |
| a | 打开文件用于追加。如果文件不存在,则创建该文件;如果文件已存在,则将写入内容追加到文件尾部。 |
| r+ | 打开文件用于读写。如果文件不存在,则返回 NULL。 |
| w+ | 打开文件用于读写。如果文件不存在,则创建该文件;如果文件已存在,则清空文件内容。 |
| a+ | 打开文件用于追加或读写。如果文件不存在,则创建该文件;如果文件已存在,则将写入内容追加到文件尾部。 |
需要注意的是,使用w或w+模式打开文件,会清空文件内容,这一点需要特别注意。
调用fclose()函数一般形式:
- int fclose(FILE *fp);
- //提示
- fclose(文件指针变量);
-
- #include
-
- int main() {
- FILE *fp;
- fp = fopen("test.txt", "w");
- if (fp == NULL) {
- printf("Error opening file.\n");
- return 1;
- }
- fprintf(fp, "Hello, world!\n");
- fclose(fp);
- return 0;
- }
-
这个程序的功能是打开名为test.txt的文件,并向其中写入一行字符串"Hello, world!\n"。如果文件打开失败,则输出错误信息并返回1;否则将字符串写入文件并关闭文件,返回0。
提示:在C语言中文件的操作都是由库函数完成,同时,文件的打开实际上就是文件与文件指针之间的联系,以便进行操作,文件的关闭实际上也是断开文件与文件指针之间的联系,即禁止对该文件操作
ch=fgetc(fp);
作用:从指针变量fp指向的文件中读取一个字符赋给字符变量ch
函数的返回值为字符变量ch,若字符变量ch是文件的结束标志”EFO“,则返回值为EFO。
下面是一个使用fgetc()函数从文件中读取一个字符的简单案例:
- #include
-
- int main() {
- FILE *fp;
- int ch;
-
- fp = fopen("test.txt", "r");
- if (fp == NULL) {
- printf("Error opening file.\n");
- return 1;
- }
-
- ch = fgetc(fp); // 从文件中读取一个字符
- if (ch == EOF) {
- printf("End of file reached.\n");
- } else {
- printf("Character read: %c\n", ch);
- }
-
- fclose(fp);
- return 0;
- }
在上面的例子中,我们打开了一个文件"test.txt",然后使用fgetc()函数从文件中读取一个字符。如果读取到了EOF(end of file),则输出"End of file reached.";否则输出读取到的字符。最后关闭文件。
fputc(ch,fp);
作用:把字符变量ch的值输出到指针变量fp指向的文件
若函数执行成功,则其返回值为输出的字符变量ch,否则返回值为文件结束标志"EFO",EFO是一个字符常量,在stdio.h头文件被定义为-1
下面是一个简单的例子,使用fputc()函数将一个字符写入文件:
- #include
-
- int main() {
- FILE *fp;
- fp = fopen("test.txt", "w");
- if (fp == NULL) {
- printf("Error opening file.\n");
- return 1;
- }
-
- fputc('a', fp); // 将字符'a'写入文件
- fclose(fp);
- return 0;
- }
-
在上面的例子中,我们打开了一个文件"test.txt",然后使用fputc()函数将字符'a'写入文件,最后关闭文件。
fgets(str,n,fp);
作用:从指针变量fp指向的文件中读取n-1个字符,送到字符数组str中
fputs(str,fp);
作用:把字符数组str中的字符串写入指针变量fp指向的文件中,但字符串结束标志“\0”不会输出
这些函数的用法与前面讲述的标准输入输出函数类似,只不过多了一个格式化字符串参数,用于指定数据的格式。下面是一个示例代码:
- #include
-
- int main() {
- FILE *fp;
- char str[100];
- int num;
-
- // 从标准输入中读取字符串和整数
- printf("请输入一个字符串:");
- scanf("%s", str);
- printf("请输入一个整数:");
- scanf("%d", &num);
-
- // 将字符串和整数格式化输出到标准输出流中
- printf("您输入的字符串是:%s\n", str);
- printf("您输入的整数是:%d\n", num);
-
- // 将字符串和整数格式化输出到文件中
- fp = fopen("test.txt", "w");
- fprintf(fp, "您输入的字符串是:%s\n", str);
- fprintf(fp, "您输入的整数是:%d\n", num);
- fclose(fp);
-
- // 从文件中读取字符串和整数
- fp = fopen("test.txt", "r");
- fscanf(fp, "%s %d", str, &num);
- fclose(fp);
-
- // 输出从文件中读取的字符串和整数
- printf("从文件中读取的字符串是:%s\n", str);
- printf("从文件中读取的整数是:%d\n", num);
-
- return 0;
- }
-
在上面的示例代码中,我们使用了scanf()函数从标准输入中读取数据,用printf()函数将数据格式化输出到标准输出流中,用fprintf()函数将数据格式化输出到文件中,用fscanf()函数从文件中读取数据。
数据块读写函数指的是一次性读写多个字节或数据块的函数,常见的数据块读写函数有fread()和fwrite()函数。
fread()函数的一般形式为:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
其中,ptr为指向要读入数据的指针,size为每个数据块的大小(以字节为单位),count为要读入的数据块个数,stream为指向文件的指针,返回值为实际读入的数据块个数。
下面是一个简单的例子,使用fread()函数从文件中读取一个数据块:
- #include
-
- int main() {
- FILE *fp;
- fp = fopen("test.txt", "rb");
- if (fp == NULL) {
- printf("Error opening file.\n");
- return 1;
- }
-
- char buffer[100];
- int n = fread(buffer, sizeof(char), 50, fp); // 从文件中读取50个字符
- printf("Read %d bytes from file.\n", n);
- fclose(fp);
- return 0;
- }
在上面的例子中,我们打开了一个文件"test.txt",然后使用fread()函数从文件中读取50个字符,最后输出实际读入的字节数。需要注意的是,在使用fread()函数读取二进制文件时,需要使用"rb"模式打开文件。
fwrite()函数的一般形式为:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
其中,ptr为指向要写出数据的指针,size为每个数据块的大小(以字节为单位),count为要写出的数据块个数,stream为指向文件的指针,返回值为实际写出的数据块个数。
下面是一个简单的例子,使用fwrite()函数将一个数据块写入文件:
- #include
-
- int main() {
- FILE *fp;
- fp = fopen("test.txt", "wb");
- if (fp == NULL) {
- printf("Error opening file.\n");
- return 1;
- }
-
- char buffer[] = "hello world";
- int n = fwrite(buffer, sizeof(char), 11, fp); // 将11个字符写入文件
- printf("Write %d bytes to file.\n", n);
- fclose(fp);
- return 0;
- }
在上面的例子中,我们打开了一个文件"test.txt",然后使用fwrite()函数将一个数据块("hello world")写入文件,最后输出实际写出的字节数。需要注意的是,在使用fwrite()函数写入二进制文件时,需要使用"wb"模式打开文件。
文件的基本定位指的是通过文件指针对文件进行读写时,如何定位到指定的位置进行读写。
常见的文件定位函数有fseek()和ftell()函数。
int fseek(FILE *stream, long offset, int whence);
其中,stream为文件指针,offset为偏移量,whence表示起始位置。
偏移量offset表示相对于whence起始位置的偏移量,其数值和符号取决于whence的值。whence的值有三个,分别为SEEK_SET、SEEK_CUR和SEEK_END,表示从文件开头、当前位置和文件末尾开始偏移。
示例代码:
- #include
-
- int main() {
- FILE *fp;
- char str[] = "Hello, world!";
- int len = sizeof(str);
-
- fp = fopen("test.txt", "w");
- fwrite(str, sizeof(char), len, fp);
- fclose(fp);
-
- fp = fopen("test.txt", "r");
- fseek(fp, 7, SEEK_SET); // 将文件指针移动到字符串"world!"的起始位置
- while (fgetc(fp) != EOF) { // 逐个字符读取到文件末尾
- putchar(fgetc(fp)); // 输出"world!"
- }
- fclose(fp);
-
- return 0;
- }
long ftell(FILE *stream);
其中,stream为文件指针。函数返回值为文件指针当前的位置,以字节为单位。如果发生错误,返回值为-1。
示例代码:
- #include
-
- int main() {
- FILE *fp;
- char str[] = "Hello, world!";
- int len = sizeof(str);
-
- fp = fopen("test.txt", "w");
- fwrite(str, sizeof(char), len, fp);
- fclose(fp);
-
- fp = fopen("test.txt", "r");
- fseek(fp, 7, SEEK_SET); // 将文件指针移动到字符串"world!"的起始位置
- long pos = ftell(fp); // 获取当前位置,并输出到控制台
- printf("Current position: %ld\n", pos); // 输出"Current position: 7"
- fclose(fp);
-
- return 0;
- }
void rewind(FILE *stream)
其中,stream为文件指针。函数无返回值。
简单的C语言项目,用于将输入的字符串写入到文件中,并识别错误代码。
- #include
- #include
- #include
-
- #define MAX_LEN 1000
-
- int main() {
- char str[MAX_LEN];
- FILE *fp;
-
- // 打开文件
- fp = fopen("output.txt", "w");
- if (fp == NULL) {
- printf("Error: failed to open file.\n");
- exit(1);
- }
-
- // 获取输入字符串
- printf("Enter a string: ");
- fgets(str, MAX_LEN, stdin);
- str[strcspn(str, "\n")] = 0; // 去掉末尾的换行符
-
- // 写入字符串到文件中
- if (fwrite(str, sizeof(char), strlen(str), fp) != strlen(str)) {
- printf("Error: failed to write to file.\n");
- exit(1);
- }
-
- // 关闭文件
- fclose(fp);
-
- printf("String written to file successfully.\n");
- return 0;
- }
在这个项目中,我们使用了C语言中的文件操作函数。我们首先定义了一个字符串数组 str 和一个文件指针 fp,然后通过 fopen 函数打开一个名为 output.txt 的文件,打开方式为写入模式。如果打开文件失败,则会输出错误信息并退出程序。
接着,我们使用 fgets 函数从标准输入中获取用户输入的字符串,并使用 strcspn 函数去掉末尾的换行符。然后,我们使用 fwrite 函数将字符串写入到文件中,如果写入失败则会输出错误信息并退出程序。最后,我们使用 fclose 函数关闭文件,并输出写入成功的提示信息。