一.文件
1.文件
文件是计算机中存储数据的一种方式,它是一组按照特定格式组织的数据的集合。文件可以包含文本、图像、音频、视频等各种类型的数据。
在计算机系统中,文件是存储在存储介质(如硬盘、固态硬盘、光盘等)上的一段连续或间断的数据。每个文件都有一个唯一的名称,用于在文件系统中进行标识和访问。
文件可以用于多种目的,例如:
-
存储和维护文本数据:文本文件包含可由文本编辑器打开和编辑的字符数据。这些文件通常用于存储配置信息、日志文件、源代码文件等。
-
存储和处理二进制数据:二进制文件包含以二进制格式编码的数据,如图像、音频、视频文件。这些文件需要特定的应用程序或解码器来读取和处理。
-
存储和传输数据:文件是在计算机系统之间传输和共享数据的主要方式。通过将数据写入文件,可以将数据保存在磁盘上,并在需要时进行读取和处理。
计算机中的文件通常由文件名和文件扩展名组成。文件名是文件的唯一标识符,而文件扩展名表示文件的类型或格式。例如,"document.txt"中,"document"是文件名,".txt"是文件扩展名,表示这是一个文本文件。
文件操作是计算机编程中常见的任务之一,通过使用编程语言提供的文件操作函数,可以创建、打开、读取、写入和关闭文件,以及对文件进行其他处理操作。
2.二进制文件和文本文件
二进制文件和文本文件是存储数据的两种不同形式。
-
文本文件(Text File):
- 文本文件是由字符组成的文件,其中每个字符都使用字符编码(如ASCII或Unicode)进行表示。
- 文本文件包含可读的文本内容,通常由人类可读的字符组成,比如字母、数字、标点符号等。
- 文本文件可以使用文本编辑器(如记事本、Sublime Text等)打开和编辑。
- 在文本文件中,文本的格式和结构通常是有意义的,比如换行符表示新的一行,制表符用于对齐等。
- 文本文件可以包含纯文本数据、配置文件、源代码等。
- 示例文件扩展名:.txt、.csv、.html、.c、.java 等。
-
二进制文件(Binary File):
- 二进制文件包含以二进制形式编码的数据,不是直接由人类可读的文本。
- 二进制文件可以包含任意类型的数据,如图像、音频、视频、执行代码、数据库文件等。
- 二进制文件的内容由计算机程序或特定应用程序进行解释和处理。
- 与文本文件不同,二进制文件没有明确的字符编码,其内容以字节为单位进行编码。
- 二进制文件可以包含非文本数据,如图像文件的像素值、音频文件的采样数据等。
- 示例文件扩展名:.jpg、.mp3、.avi、.exe、.dat 等。
在文件操作中,读取和写入文本文件通常使用文本模式,而读取和写入二进制文件则使用二进制模式。文本文件可以通过简单的文本编辑器进行编辑和查看,而二进制文件通常需要特定的应用程序或解码器来解释和处理。
需要注意的是,尽管文本文件和二进制文件有所区别,但在某些情况下,二者之间的界限可以模糊。例如,文本文件也可以包含二进制数据(如文本文件中的图像数据),而某些二进制文件(如XML或JSON文件)可以使用文本编辑器进行部分查看和编辑。
二.流和标准流
在C语言中,流(stream)是一种用于输入和输出的抽象概念。它提供了一种统一的方式来处理各种输入和输出设备,例如键盘、文件和网络连接。C语言中的标准库提供了三个预定义的流,称为标准流(standard streams),它们分别是标准输入流(stdin)、标准输出流(stdout)和标准错误流(stderr)。
以下是有关流和标准流的一些重要信息:
-
标准输入流(stdin):标准输入流是用于从键盘或其他输入设备读取数据的流。在C语言中,可以使用
scanf
函数从stdin中读取输入。 -
标准输出流(stdout):标准输出流是用于将数据输出到屏幕或其他输出设备的流。在C语言中,可以使用
printf
函数将数据输出到stdout。 -
标准错误流(stderr):标准错误流是用于将错误消息和诊断信息输出到屏幕或其他输出设备的流。在C语言中,可以使用
fprintf
函数将错误消息输出到stderr。
这些标准流在程序执行时自动打开,并且无需显式地打开或关闭。它们具有以下特点:
- stdin通常与键盘关联,可以使用
scanf
函数从stdin读取用户输入。 - stdout通常与屏幕关联,可以使用
printf
函数将输出打印到屏幕。 - stderr通常与屏幕关联,可以使用
fprintf
函数将错误消息打印到屏幕。
下面是一个简单的示例,演示如何使用标准输入流(stdin)和标准输出流(stdout)读取用户输入并将其打印到屏幕:
#include <stdio.h>
int main() {
char name[50];
int age;
printf("Enter your name: ");
scanf("%s", name); // 从stdin读取输入
printf("Enter your age: ");
scanf("%d", &age); // 从stdin读取输入
printf("Name: %s\n", name); // 将输出打印到stdout
printf("Age: %d\n", age); // 将输出打印到stdout
return 0;
}
三.文件函数
1.文件的打开和关闭
C语言提供了一组文件操作函数,用于创建、打开、读取、写入和关闭文件。这些函数包含在C标准库的"stdio.h"头文件中。下面是一些常用的文件操作函数:
-
fopen(): 用于打开一个文件,并返回一个文件指针。它接受两个参数,第一个参数是文件名(包括路径),第二个参数是打开模式(例如,"r"表示只读,"w"表示写入,"a"表示追加)。
-
文件打开模式:
- "r": 只读模式,打开一个已存在的文件进行读取。
- "w": 写入模式,打开一个文件进行写入。如果文件不存在,则创建一个新文件;如果文件存在,则截断文件(即清空文件内容)。
- "a": 追加模式,打开一个文件进行写入。如果文件不存在,则创建一个新文件;如果文件存在,则将数据追加到文件末尾。
- "b": 二进制模式,用于以二进制格式进行读写操作。
- "t": 文本模式,用于以文本格式进行读写操作(默认模式)。
-
fclose(): 用于关闭一个已打开的文件。它接受一个文件指针作为参数。
2.文件的顺序读写
-
fgetc(): 用于从文件中读取一个字符。它接受一个文件指针作为参数,并返回读取的字符。
-
fputc(): 用于将一个字符写入文件。它接受两个参数,第一个参数是要写入的字符,第二个参数是文件指针。
-
fgets(): 用于从文件中读取一行数据(包括换行符)。它接受三个参数,第一个参数是存储读取数据的字符串缓冲区,第二个参数是缓冲区的大小,第三个参数是文件指针。
-
fputs(): 用于将一行数据写入文件(不包括换行符)。它接受两个参数,第一个参数是要写入的字符串,第二个参数是文件指针。
-
fprintf(): 用于将格式化数据写入文件。它的用法与printf()函数类似,但是第一个参数是文件指针。
-
fscanf(): 用于从文件中读取格式化的数据。它的用法与scanf()函数类似,但是第一个参数是文件指针。
3.文件的随机读写
-
fseek(): 用于在文件中进行定位。它接受三个参数,第一个参数是文件指针,第二个参数是偏移量,第三个参数是起始位置。偏移量可以是正数、负数或零,起始位置可以是SEEK_SET(文件开头)、SEEK_CUR(当前位置)或SEEK_END(文件末尾)。
4.文件的结束判断
-
feof(): 用于检测文件结束符。它接受一个文件指针作为参数,并在文件结束时返回非零值。
四.文件操作的示例
- 读取文件内容并打印到控制台:
#include <stdio.h> int main() { FILE *file = fopen("example.txt", "r"); // 打开文件以供读取 if (file == NULL) { // 检查文件是否成功打开 perror("Failed to open the file"); // 打印错误消息 return 1; } char ch; while ((ch = fgetc(file)) != EOF) { // 逐个字符读取文件内容 putchar(ch); // 打印字符到控制台 } fclose(file); // 关闭文件 return 0; }
- 将用户输入的文本写入文件:
#include <stdio.h> int main() { FILE *file = fopen("output.txt", "w"); // 打开文件以供写入 if (file == NULL) { // 检查文件是否成功打开 perror("Failed to open the file"); // 打印错误消息 return 1; } char text[100]; printf("Enter some text: "); fgets(text, sizeof(text), stdin); // 从用户输入读取文本 fputs(text, file); // 将文本写入文件 fclose(file); // 关闭文件 return 0; }
- 以二进制模式读写二进制文件:
#include <stdio.h> typedef struct { int id; char name[20]; float salary; } Employee; int main() { FILE *file = fopen("employees.dat", "wb"); // 以二进制写入模式打开文件 if (file == NULL) { // 检查文件是否成功打开 perror("Failed to open the file"); // 打印错误消息 return 1; } Employee emp1 = {1, "John Doe", 5000.0}; Employee emp2 = {2, "Jane Smith", 6000.0}; fwrite(&emp1, sizeof(Employee), 1, file); // 将结构体写入文件 fwrite(&emp2, sizeof(Employee), 1, file); fclose(file); // 关闭文件 file = fopen("employees.dat", "rb"); // 以二进制读取模式打开文件 if (file == NULL) { // 检查文件是否成功打开 perror("Failed to open the file"); // 打印错误消息 return 1; } Employee emp; while (fread(&emp, sizeof(Employee), 1, file) == 1) { // 从文件读取结构体 printf("ID: %d, Name: %s, Salary: %.2f\n", emp.id, emp.name, emp.salary); // 打印结构体内容 } fclose(file); // 关闭文件 return 0; }
- 逐行读取文本文件并计算行数:
#include <stdio.h> int main() { FILE *file = fopen("example.txt", "r"); // 打开文件以供读取 if (file == NULL) { // 检查文件是否成功打开 perror("Failed to open the file"); // 打印错误消息 return 1; } char line[100]; int lineCount = 0; while (fgets(line, sizeof(line), file) != NULL) { // 逐行读取文件内容 lineCount++; // 计数器递增 } printf("Number of lines: %d\n", lineCount); fclose(file); // 关闭文件 return 0; }
- 在文本文件末尾追加内容:
#include <stdio.h> int main() { FILE *file = fopen("example.txt", "a"); // 以追加模式打开文件 if (file == NULL) { // 检查文件是否成功打开 perror("Failed to open the file"); // 打印错误消息 return 1; } fprintf(file, "This is a new line.\n"); // 在文件末尾追加内容 fclose(file); // 关闭文件 return 0; }
- 检查文件是否存在:
#include <stdio.h> int main() { const char *filename = "example.txt"; FILE *file = fopen(filename, "r"); if (file != NULL) { printf("File '%s' exists.\n", filename); fclose(file); } else { printf("File '%s' does not exist.\n", filename); } return 0; }
- 删除文件:
#include <stdio.h> int main() { const char *filename = "example.txt"; if (remove(filename) == 0) { printf("File '%s' deleted successfully.\n", filename); } else { perror("Failed to delete the file"); // 打印错误消息 } return 0; }
希望以上的内容能帮到你!感谢你的阅读。