学期2024-2025-1 学号20241306 《计算机基础与程序设计》第13周学习总结

作业信息

这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计(https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP))
这个作业要求在哪里 2024-2025-1计算机基础与程序设计第13周作业
这个作业的目标 C语言程序设计第12章
作业正文 ... 本博客链接

教材学习内容总结

文件操作概述
文件概念
在 C 语言中,文件是存储在外部介质(如磁盘)上的数据集合。它可以是程序文件(包括源文件、目标文件、可执行文件等)或者数据文件。数据文件能够用来存储程序运行时所需的输入数据或者程序产生的输出结果。
文件通常分为文本文件和二进制文件。文本文件是字符序列,便于人类阅读,在存储时每个字符以 ASCII 码等编码方式存储;二进制文件则以二进制形式存储数据,例如存储一个整数,在二进制文件中就是其对应的二进制编码,这种文件对于计算机处理更加高效,但对人来说可读性差。
文件指针
文件指针是 C 语言中用于操作文件的重要概念。定义格式一般为FILE *指针变量名;,例如FILE *fp;。这个指针变量指向一个包含文件相关信息(如文件名、文件状态、当前读写位置等)的结构体。通过这个指针,可以访问和操作文件。
文件的打开与关闭
fopen 函数
用于打开文件,函数原型为FILE *fopen(const char *filename, const char *mode);。其中filename是要打开文件的文件名(可以包含路径),mode是文件的打开方式。
打开方式常见的有:
"r":以只读方式打开文本文件。如果文件不存在,则打开失败。
"w":以只写方式打开文本文件。如果文件存在,则清空文件内容;如果文件不存在,则创建新文件。
"a":以追加方式打开文本文件。如果文件存在,则在文件末尾追加内容;如果文件不存在,则创建新文件。
"rb"、"wb"、"ab":分别是对二进制文件进行只读、只写、追加操作的模式。
例如fp = fopen("test.txt", "r");尝试以只读方式打开当前目录下名为test.txt的文件,并将文件指针赋值给fp。如果打开成功,fp就指向这个文件;如果失败,fp的值为NULL。
fclose 函数
用于关闭已经打开的文件,函数原型为int fclose(FILE *stream);。在文件操作完成后,必须关闭文件,以释放文件相关资源。如果成功关闭文件,函数返回 0;如果出现错误(如文件指针无效等),返回EOF(-1)。例如fclose(fp);关闭之前打开并由fp指向的文件。
文件的读写操作
字符读写函数
fgetc 函数:从指定文件中读取一个字符,函数原型为int fgetc(FILE *stream);。它返回读取到的字符(以int类型返回,但可以赋值给char类型变量),如果遇到文件末尾或者出错,返回EOF。例如:
c
FILE *fp;
char ch;
fp = fopen("test.txt", "r");
if (fp!= NULL) {
ch = fgetc(fp);
while (ch!= EOF) {
// 对读取的字符进行操作,例如打印
putchar(ch);
ch = fgetc(fp);
}
fclose(fp);
}
fputc 函数:将一个字符写入指定文件,函数原型为int fputc(int c, FILE *stream);。其中c是要写入的字符(可以是字符常量或者字符变量),如果写入成功,返回写入的字符;如果出错,返回EOF。例如fputc('A', fp);将字符A写入fp指向的文件。
字符串读写函数
fgets 函数:从文件中读取一个字符串,函数原型为char *fgets(char *str, int n, FILE *stream);。str是用来存储读取字符串的字符数组,n是读取的字符个数上限(一般要预留一个位置给字符串结束符\0)。读取成功时返回str(也就是字符串的首地址),如果遇到文件末尾或者出错,返回NULL。例如:
c
char str[100];
FILE *fp;
fp = fopen("test.txt", "r");
if (fp!= NULL) {
fgets(str, 100, fp);
// 对读取的字符串进行操作,例如打印
printf("%s", str);
fclose(fp);
}
fputs 函数:将一个字符串写入文件,函数原型为int fputs(const char *str, FILE *stream);。str是要写入的字符串常量或者字符数组。如果写入成功,返回一个非负整数;如果出错,返回EOF。例如fputs("Hello, World!", fp);将字符串"Hello, World!"写入fp指向的文件。
格式化读写函数
fscanf 函数:从文件中按照指定格式读取数据,函数原型为int fscanf(FILE *stream, const char *format,...);。和scanf函数类似,不过它是从文件读取而不是从标准输入读取。例如从文件中读取两个整数:
c
int num1, num2;
FILE *fp;
fp = fopen("data.txt", "r");
if (fp!= NULL) {
fscanf(fp, "%d %d", &num1, &num2);
// 对读取的整数进行操作
printf("num1 = %d, num2 = %d\n", num1, num2);
fclose(fp);
}
fprintf 函数:将数据按照指定格式写入文件,函数原型为int fprintf(FILE *stream, const char *format,...);。和printf函数类似,不过是写入文件而不是输出到标准输出。例如fprintf(fp, "The numbers are %d and %d", num1, num2);将包含两个整数的信息写入fp指向的文件。
块读写函数(二进制文件读写)
fread 函数:用于从二进制文件中读取数据块,函数原型为size_t fread(void *ptr, size_t size, size_t count, FILE *stream);。ptr是存储读取数据的内存地址,size是每个数据元素的大小,count是要读取的元素个数。返回值是实际读取的元素个数。例如读取一个包含 10 个整数的二进制文件:
c
int arr[10];
FILE *fp;
fp = fopen("binary_data.bin", "rb");
if (fp!= NULL) {
size_t result = fread(arr, sizeof(int), 10, fp);
if (result == 10) {
// 数据读取成功,对数组进行操作
}
fclose(fp);
}
fwrite 函数:用于将数据块写入二进制文件,函数原型为size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);。ptr是要写入数据的内存起始地址,size是每个数据元素大小,count是要写入的元素个数。返回值是实际写入的元素个数。例如将一个数组写入二进制文件:
c
int arr[5] = {1, 2, 3, 4, 5};
FILE *fp;
fp = fopen("binary_data.bin", "wb");
if (fp!= NULL) {
size_t result = fwrite(arr, sizeof(int), 5, fp);
if (result == 5) {
// 数据写入成功
}
fclose(fp);
}
文件的定位操作
ftell 函数:用于获取文件指针的当前位置(相对于文件开头的偏移量),函数原型为long ftell(FILE *stream);。如果成功,返回当前位置;如果出错,返回-1L。例如long pos = ftell(fp);获取fp指向文件的当前位置。
fseek 函数:用于移动文件指针到指定位置,函数原型为int fseek(FILE *stream, long offset, int whence);。offset是偏移量,whence是基准位置,可以取SEEK_SET(文件开头)、SEEK_CUR(当前位置)、SEEK_END(文件末尾)。例如fseek(fp, 10L, SEEK_SET);将文件指针从文件开头移动 10 个字节的位置。
rewind 函数:将文件指针重新定位到文件开头,函数原型为void rewind(FILE *stream);。相当于fseek(fp, 0L, SEEK_SET);,不过rewind函数没有返回值。

教材学习中的问题和解决过程(先问 AI)

  • 问题1:C语言中文件关闭的重要性
  • 问题1解决方案:
    资源释放
    在 C 语言中,当打开一个文件时,操作系统会为该文件操作分配一定的资源,如文件描述符、缓冲区等。文件描述符用于在操作系统层面唯一标识一个打开的文件,缓冲区则用于临时存储文件读写的数据,以提高读写效率。
    以fopen函数打开文件为例,当程序执行FILE *fp = fopen("example.txt","r");时,操作系统会为这个文件操作分配资源。如果不关闭文件,这些资源会一直被占用。而fclose(fp);会释放这些相关资源,使得操作系统可以将这些资源重新分配给其他需要进行文件操作的程序或者进程。
    数据完整性保障
    在文件写入操作时,C 语言通常会使用缓冲区来优化写入性能。当数据被写入文件时,它可能首先被存储在缓冲区中,而不是立即写入磁盘。
    例如,使用fputc或fwrite函数写入数据后,如果不关闭文件,缓冲区中的数据可能没有完全写入磁盘。当程序意外终止(如崩溃、断电等情况)时,这些还在缓冲区中的数据就会丢失。而关闭文件会触发缓冲区的刷新,将缓冲区中剩余的数据全部写入磁盘,确保数据的完整性。
    假设一个程序不断地向文件中写入日志信息,每次写入一部分数据到缓冲区。如果在没有关闭文件的情况下程序结束,那么最后一部分还在缓冲区中的日志数据可能就不会被记录到文件中,导致日志文件不完整。
    避免文件损坏和错误
    多个程序或进程可能需要访问同一个文件。如果一个程序打开文件进行写操作后没有正确关闭,另一个程序尝试打开同一文件进行读写时可能会出现错误。
    例如,一个程序以写模式打开文件但没有关闭,另一个程序又试图以读模式打开这个文件,可能会导致无法正确读取文件内容,甚至可能损坏文件的元数据(如文件大小、权限等)。而且,在一些操作系统中,对一个没有正确关闭的文件再次进行打开操作可能会受到限制,因为操作系统认为该文件仍处于被占用的状态。
    良好的编程习惯和程序健壮性
    关闭文件是一种良好的编程习惯。它可以使程序更加健壮和可靠。在一个复杂的程序中,可能会有多个文件操作,如果其中一些文件没有正确关闭,随着程序的运行,可能会逐渐耗尽系统资源,导致程序出现各种不可预测的错误,如内存泄漏、文件操作失败等。
    比如一个大型的 C 程序,它需要同时处理多个输入文件和输出文件。如果在处理每个文件后不及时关闭,随着文件数量的增加,可能会导致程序最终因为资源耗尽而崩溃。及时关闭文件可以避免这类问题,提高程序的整体质量。
  • 问题2:文本文件和二进制文件有什么区别
  • 问题2解决方案:
    存储内容格式
    文本文件:
    文本文件存储的是字符的编码序列,通常采用 ASCII 码、UTF - 8 等字符编码方式。例如,在 ASCII 码中,字符 'A' 对应的编码是 65(十进制)。当我们在文本文件中写入字符 'A' 时,实际存储的是 65 这个数值对应的二进制表示(01000001)。
    文本文件以字符为单位进行存储,内容对人类是可读的。比如一个简单的文本文件包含句子 “Hello, World!”,在文件中就是按照字符的编码逐个存储这些字符的编码值。
    二进制文件:
    二进制文件直接存储数据的二进制表示形式。如果存储一个整数,比如整数 10,在二进制文件中存储的就是 10 的二进制形式(1010)。
    它可以存储各种类型的数据,包括整数、浮点数、结构体等,存储方式是按照数据在内存中的实际二进制存储格式进行存储。例如,对于一个包含多个结构体的二进制文件,每个结构体中的成员变量按照其在内存中的布局依次存储。
    文件大小和存储效率
    文本文件:
    由于文本文件存储的是字符编码,对于一些非 ASCII 字符(如汉字等),在 UTF - 8 等编码下可能需要多个字节来表示一个字符。例如,一个汉字在 UTF - 8 编码下可能需要 3 个字节。
    文本文件相对二进制文件来说,存储相同的数据可能会占用更多的空间。而且在存储数字等数据时,如果以文本形式存储,会有一定的空间浪费。比如存储整数 10000,在文本文件中是存储这 5 个字符的编码,而在二进制文件中只需要 2 个字节(假设为 16 位整数)。
    二进制文件:
    二进制文件存储数据的方式更加紧凑和高效。它直接存储数据的二进制形式,没有字符编码的转换开销。对于大量的数据存储,尤其是包含多种数据类型的数据,二进制文件能够节省存储空间。
    例如,存储一个由 1000 个整数组成的数组,在二进制文件中按照整数的二进制格式存储,比将这些整数转换为字符形式存储在文本文件中要节省很多空间。
    读写操作方式
    文本文件:
    读写文本文件时,通常使用面向字符或面向字符串的函数,如fgetc(读取一个字符)、fgets(读取一个字符串)、fputc(写入一个字符)和fputs(写入一个字符串)等。这些函数在读写时会自动处理字符编码的转换。
    例如,当使用fgets从文本文件中读取一个字符串时,它会根据指定的长度读取字符,并在遇到换行符\n或者达到指定长度时停止读取,然后将读取到的字符串存储在指定的字符数组中。
    二进制文件:
    读写二进制文件主要使用fread和fwrite函数。这些函数以数据块为单位进行读写操作,需要指定数据的大小和数量。
    比如,要从二进制文件中读取一个结构体,需要明确结构体的大小,并使用fread函数按照结构体的大小和数量(这里是 1 个结构体)进行读取操作。在操作过程中,不会进行字符编码的转换,因为存储的就是数据的原始二进制形式。
    适用场景
    文本文件:
    适合存储和处理文本信息,如程序的源代码、配置文件、日志文件等。因为这些文件的内容主要是供人阅读和编辑的。
    例如,一个程序的配置文件,里面包含了各种参数的设置,如 “port = 8080”,以文本文件形式存储方便用户直接修改这些参数。
    二进制文件:
    适用于存储需要高效存储和快速读取的数据,特别是那些需要在程序之间直接传递和处理的数据。比如,图像、音频、视频文件等通常是二进制文件,因为这些文件的数据格式复杂,采用二进制存储可以更好地保持数据的完整性和高效性。
    例如,一个 PNG 图像文件,它的文件头、像素数据等都是以二进制形式存储的,这样在图像处理软件读取和处理时能够更高效地解析和操作这些数据。

基于AI的学习


posted @ 2024-12-22 20:26  20241306吴军磊  阅读(3)  评论(0编辑  收藏  举报