- C编程教程
- C - 首页
- C语言基础
- C - 概述
- C - 特性
- C - 历史
- C - 环境设置
- C - 程序结构
- C - Hello World
- C - 编译过程
- C - 注释
- C - 词法单元
- C - 关键字
- C - 标识符
- C - 用户输入
- C - 基本语法
- C - 数据类型
- C - 变量
- C - 整数提升
- C - 类型转换
- C - 类型强制转换
- C - 布尔值
- C语言中的常量和字面量
- C - 常量
- C - 字面量
- C - 转义序列
- C - 格式说明符
- C语言中的运算符
- C - 运算符
- C - 算术运算符
- C - 关系运算符
- C - 逻辑运算符
- C - 位运算符
- C - 赋值运算符
- C - 一元运算符
- C - 自增和自减运算符
- C - 三元运算符
- C - sizeof 运算符
- C - 运算符优先级
- C - 其他运算符
- C语言中的决策
- C - 决策
- C - if 语句
- C - if...else 语句
- C - 嵌套 if 语句
- C - switch 语句
- C - 嵌套 switch 语句
- C语言中的循环
- C - 循环
- C - while 循环
- C - for 循环
- C - do...while 循环
- C - 嵌套循环
- C - 无限循环
- C - break 语句
- C - continue 语句
- C - goto 语句
- C语言中的函数
- C - 函数
- C - 主函数
- C - 按值调用函数
- C - 按引用调用函数
- C - 嵌套函数
- C - 可变参数函数
- C - 用户自定义函数
- C - 回调函数
- C - 返回语句
- C - 递归
- C语言中的作用域规则
- C - 作用域规则
- C - 静态变量
- C - 全局变量
- C语言中的数组
- C - 数组
- C - 数组的特性
- C - 多维数组
- C - 将数组传递给函数
- C - 从函数返回数组
- C - 可变长数组
- C语言中的指针
- C - 指针
- C - 指针和数组
- C - 指针的应用
- C - 指针运算
- C - 指针数组
- C - 指针到指针
- C - 将指针传递给函数
- C - 从函数返回指针
- C - 函数指针
- C - 指向数组的指针
- C - 指向结构体的指针
- C - 指针链
- C - 指针与数组
- C - 字符指针和函数
- C - 空指针
- C - void 指针
- C - 悬空指针
- C - 解引用指针
- C - 近、远和巨型指针
- C - 指针数组的初始化
- C - 指针与多维数组
- C语言中的字符串
- C - 字符串
- C - 字符串数组
- C - 特殊字符
- C语言中的结构体和联合体
- C - 结构体
- C - 结构体和函数
- C - 结构体数组
- C - 自引用结构体
- C - 查找表
- C - 点(.)运算符
- C - 枚举(或枚举类型)
- C - 结构体填充和打包
- C - 嵌套结构体
- C - 匿名结构体和联合体
- C - 联合体
- C - 位域
- C - Typedef
- C语言文件处理
- C - 输入与输出
- C - 文件I/O(文件处理)
- C预处理器
- C - 预处理器
- C - 指令
- C - 预处理器运算符
- C - 宏
- C - 头文件
- C语言中的内存管理
- C - 内存管理
- C - 内存地址
- C - 存储类
- 其他主题
- C - 错误处理
- C - 可变参数
- C - 命令执行
- C - 数学函数
- C - static 关键字
- C - 随机数生成
- C - 命令行参数
- C编程资源
- C - 问答
- C - 快速指南
- C - 速查表
- C - 有用资源
- C - 讨论
C语言文件处理
C语言文件处理
C语言中的文件处理是指使用C语言函数处理文件操作的过程,例如创建、打开、写入数据、读取数据、重命名和删除。借助这些函数,我们可以在程序中执行文件操作,以便在文件中存储和检索数据。
C语言中文件处理的必要性
如果我们使用C程序执行输入和输出操作,则数据仅在程序运行期间存在,当程序终止时,我们无法再次使用该数据。文件处理需要处理存储在外部存储器中的文件,即从计算机的外部存储器存储和访问信息。您可以使用文件处理永久保存数据。
文件的类型
文件表示一系列字节。文件有两种类型:文本文件和二进制文件。
- 文本文件 - 文本文件以ASCII字符的形式包含数据,通常用于存储字符流。文本文件中的每一行以换行符("\n")结尾,通常具有".txt"扩展名。
- 二进制文件 - 二进制文件以原始位(0和1)的形式包含数据。不同的应用程序程序有不同的表示位和字节的方法,并使用不同的文件格式。图像文件(.png,.jpg),可执行文件(.exe,.com)等是二进制文件的示例。
文件指针 (File*)
在处理文件处理时,您需要一个文件指针来存储fopen()函数返回的FILE结构的引用。所有文件处理操作都需要文件指针。
fopen()函数 返回FILE类型的指针。FILE是stdio.h中预定义的结构体类型,包含文件描述符、大小和位置等属性。
typedef struct { int fd; /* File descriptor */ unsigned char *buf; /* Buffer */ size_t size; /* Size of the file */ size_t pos; /* Current position in the file */ } FILE;
声明文件指针 (FILE*)
以下是声明文件指针的语法:
FILE* file_pointer;
打开(创建)文件
必须打开文件才能执行任何操作。fopen()函数用于创建新文件或打开现有文件。您需要指定要打开的模式。下面解释了各种文件打开模式,在创建/打开文件时可以使用其中任何一种。
fopen()函数返回一个FILE指针,该指针将用于其他操作,例如读取、写入和关闭文件。
语法
以下是打开文件的语法:
FILE *fopen(const char *filename, const char *mode);
这里,filename是要打开的文件的名称,mode定义文件的打开模式。
文件打开模式
文件访问模式默认以文本或ASCII模式打开文件。如果要处理二进制文件,则应使用以下访问模式,而不是上述模式
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
文件可以以多种模式打开。以下是不同的文件打开模式:
模式 | 描述 |
---|---|
r | 以读取目的打开现有的文本文件。 |
w | 打开文本文件以进行写入。如果文件不存在,则创建一个新文件。在此,您的程序将从文件开头开始写入内容。 |
a | 以追加模式打开文本文件以进行写入。如果文件不存在,则创建一个新文件。在此,您的程序将开始将内容追加到现有文件内容中。 |
r+ | 打开文本文件以进行读写。 |
w+ | |
a+ | 打开文本文件以进行读写。如果文件不存在,则创建文件。读取将从开头开始,但只能追加写入。 |
创建文件的示例
在以下示例中,我们正在创建一个新文件。创建新文件的文件模式将为“w”(写入模式)。
#include <stdio.h> int main() { FILE * file; // Creating a file file = fopen("file1.txt", "w"); // Checking whether file is // created or not if (file == NULL) { printf("Error in creating file"); return 1; } printf("File created."); return 0; }
输出
File created.
打开文件的示例
在以下示例中,我们正在打开一个现有文件。打开现有文件的文件模式将为“r”(只读)。您也可以使用上面解释的其他文件打开模式选项。
注意:必须存在要打开的文件。
#include <stdio.h> int main() { FILE * file; // Opening a file file = fopen("file1.txt", "r"); // Checking whether file is // opened or not if (file == NULL) { printf("Error in opening file"); return 1; } printf("File opened."); return 0; }
输出
File opened.
关闭文件
每个文件在对其执行操作后都必须关闭。 fclose()函数 关闭打开的文件。
语法
以下是fclose()函数的语法:
int fclose(FILE *fp);
fclose()函数在成功时返回零,如果关闭文件时出错则返回EOF。
fclose()函数实际上会将缓冲区中仍挂起的所有数据刷新到文件,关闭文件并释放用于文件的所有内存。EOF是头文件stdio.h中定义的常量。
关闭文件的示例
在以下示例中,我们正在关闭打开的文件:
#include <stdio.h> int main() { FILE * file; // Opening a file file = fopen("file1.txt", "w"); // Checking whether file is // opened or not if (file == NULL) { printf("Error in opening file"); return 1; } printf("File opened."); // Closing the file fclose(file); printf("\nFile closed."); return 0; }
输出
File opened. File closed.
写入文本文件
提供了以下库函数以将数据写入以可写模式打开的文件:
- fputc():将单个字符写入文件。
- fputs():将字符串写入文件。
- fprintf():将格式化字符串(数据)写入文件。
将单个字符写入文件
fputc()函数 是一个非格式化函数,它将参数“c”的单个字符值写入“fp”引用的输出流。
int fputc(int c, FILE *fp);
示例
在以下代码中,给定字符数组中的一个字符被写入以“w”模式打开的文件中
#include <stdio.h> int main() { FILE *fp; char * string = "C Programming tutorial from TutorialsPoint"; int i; char ch; fp = fopen("file1.txt", "w"); for (i = 0; i < strlen(string); i++) { ch = string[i]; if (ch == EOF) break; fputc(ch, fp); } printf ("\n"); fclose(fp); return 0; }
输出
After executing the program, "file1.txt" will be created in the current folder and the string is written to it.
将字符串写入文件
fputs()函数 将字符串“s”写入“fp”引用的输出流。如果成功,它将返回非负值,否则在发生任何错误时返回EOF。
int fputs(const char *s, FILE *fp);
示例
以下程序将给定二维字符数组中的字符串写入文件:
#include <stdio.h> int main() { FILE *fp; char *sub[] = {"C Programming Tutorial\n", "C++ Tutorial\n", "Python Tutorial\n", "Java Tutorial\n"}; fp = fopen("file2.txt", "w"); for (int i = 0; i < 4; i++) { fputs(sub[i], fp); } fclose(fp); return 0; }
输出
当程序运行时,将在当前文件夹中创建一个名为“file2.txt”的文件,并保存以下行:
C Programming Tutorial C++ Tutorial Python Tutorial Java Tutorial
将格式化字符串写入文件
fprintf()函数 将格式化的数据流发送到FILE指针表示的磁盘文件。
int fprintf(FILE *stream, const char *format [, argument, ...])
示例
在以下程序中,我们有一个名为“employee”的结构体类型数组。该结构体具有字符串、整数和浮点数元素。使用fprintf()函数,数据被写入文件。
#include <stdio.h> struct employee { int age; float percent; char *name; }; int main() { FILE *fp; struct employee emp[] = { {25, 65.5, "Ravi"}, {21, 75.5, "Roshan"}, {24, 60.5, "Reena"} }; char *string; fp = fopen("file3.txt", "w"); for (int i = 0; i < 3; i++) { fprintf(fp, "%d %f %s\n", emp[i].age, emp[i].percent, emp[i].name); } fclose(fp); return 0; }
输出
When the above program is executed, a text file is created with the name "file3.txt" that stores the employee data from the struct array.
从文本文件读取
以下库函数用于读取以读取模式打开的文件中的数据:
- fgetc():从文件读取单个字符。
- fgets():从文件读取字符串。
- fscanf():从文件读取格式化字符串。
从文件读取单个字符
fgetc() 函数从“fp”引用的输入文件中读取一个字符。返回值是读取的字符,如果发生任何错误,则返回 EOF。
int fgetc(FILE * fp);
示例
以下示例以逐字符的方式读取给定文件,直到到达文件末尾。
#include <stdio.h> int main(){ FILE *fp ; char ch ; fp = fopen ("file1.txt", "r"); while(1) { ch = fgetc (fp); if (ch == EOF) break; printf ("%c", ch); } printf ("\n"); fclose (fp); }
输出
运行代码并检查其输出:
C Programming tutorial from TutorialsPoint
从文件读取字符串
fgets() 函数从“fp”引用的输入流中读取最多“n - 1”个字符。它将读取的字符串复制到缓冲区“buf”中,并在字符串末尾附加一个空字符以终止字符串。
示例
以下程序读取给定文件中的每一行,直到检测到文件末尾:
# include <stdio.h> int main() { FILE *fp; char *string; fp = fopen ("file2.txt", "r"); while (!feof(fp)) { fgets(string, 256, fp); printf ("%s", string) ; } fclose (fp); }
输出
运行代码并检查其输出:
C Programming Tutorial C++ Tutorial Python Tutorial Java Tutorial
从文件读取格式化字符串
C 编程语言中的fscanf() 函数用于从文件读取格式化输入。
int fscanf(FILE *stream, const char *format, ...)
示例
在以下程序中,我们使用fscanf()函数读取不同类型变量中的格式化数据。通常使用格式说明符来指示字段类型(%d、%f、%s 等)。
#include <stdio.h> int main() { FILE *fp; char *s; int i, a; float p; fp = fopen ("file3.txt", "r"); if (fp == NULL) { puts ("Cannot open file"); return 0; } while (fscanf(fp, "%d %f %s", &a, &p, s) != EOF) printf ("Name: %s Age: %d Percent: %f\n", s, a, p); fclose(fp); return 0; }
输出
执行上述程序时,它会打开文本文件“file3.txt”并在屏幕上打印其内容。运行代码后,您将获得如下输出:
Name: Ravi Age: 25 Percent: 65.500000 Name: Roshan Age: 21 Percent: 75.500000 Name: Reena Age: 24 Percent: 60.500000
文件处理二进制读写函数
对于二进制文件,读写操作以二进制形式完成。您需要在访问模式中包含字符“b”(“wb”用于写入二进制文件,“rb”用于读取二进制文件)。
有两个函数可用于二进制输入和输出:fread()函数和fwrite()函数。这两个函数都应用于读取或写入内存块,通常是数组或结构。
写入二进制文件
fwrite() 函数将指定大小的字节块从缓冲区写入以二进制写入模式打开的文件。以下是使用此函数的原型
fwrite(*buffer, size, no, FILE);
示例
在以下程序中,已声明了一个名为“employee”的结构体类型的数组。我们使用fwrite()函数写入一个字节块,相当于一个employee数据的尺寸,写入以“wb”模式打开的文件中。
#include <stdio.h> struct employee { int age; float percent; char name[10]; }; int main() { FILE *fp; struct employee e[] = { {25, 65.5, "Ravi"}, {21, 75.5, "Roshan"}, {24, 60.5, "Reena"} }; char *string; fp = fopen("file4.dat", "wb"); for (int i = 0; i < 3; i++) { fwrite(&e[i], sizeof (struct employee), 1, fp); } fclose(fp); return 0; }
输出
When the above program is run, the given file will be created in the current folder. It will not show the actual data, because the file is in binary mode.
从二进制文件读取
fread() 函数从以二进制读取模式打开的文件中读取指定大小的字节块到指定大小的缓冲区。以下是使用此函数的原型
fread(*buffer, size, no, FILE);
示例
在以下程序中,已声明了一个名为“employee”的结构体类型的数组。我们使用fread()函数读取一个字节块,相当于一个employee数据的尺寸,读取以“rb”模式打开的文件中。
#include <stdio.h> struct employee { int age; float percent; char name[10]; }; int main() { FILE *fp; struct employee e; fp = fopen ("file4.dat", "rb"); if (fp == NULL) { puts ("Cannot open file"); return 0; } while (fread (&e, sizeof (struct employee), 1, fp) == 1) printf ("Name: %s Age: %d Percent: %f\n", e.name, e.age, e.percent); fclose(fp); return 0; }
输出
执行上述程序时,它会打开文件“file4.dat”并在屏幕上打印其内容。运行代码后,您将获得如下输出:
Name: Ravi Age: 25 Percent: 65.500000 Name: Roshan Age: 21 Percent: 75.500000 Name: Reena Age: 24 Percent: 60.500000
重命名文件
rename() 函数用于将现有文件从旧文件名重命名为新文件名。
语法
以下是重命名文件的语法:
int rename(const char *old_filename, const char *new_filename)
示例
#include <stdio.h> int main() { // old and new file names char * file_name1 = "file1.txt"; char * file_name2 = "file2.txt"; // Renaming old file name to new one if (rename(file_name1, file_name2) == 0) { printf("File renamed successfully.\n"); } else { perror("There is an error."); } return 0; }
输出
如果存在文件(file1.txt),则以下将是输出:
Name: Ravi Age: 25 Percent: 65.500000 Name: Roshan Age: 21 Percent: 75.500000 Name: Reena Age: 24 Percent: 60.500000