2024-2025-1 20241328 《计算机基础与程序设计》第十三周学习总结
作业信息
| 作业课程 | 2024-2025-1-计算机基础与程序设计 |
|---|---|
| 作业要求 | 2024-2025-1计算机基础与程序设计第十三周作业 |
| 作业目标 | 无 |
教材学习内容总结
《C语言程序设计》第12章 知识点总结
12.1 文件的基本概念
-
文件定义:
- 文件是存储在计算机中的一组数据,用于长期保存信息。C语言通过文件操作提供了对外部数据的访问能力。
-
文件类型:
- 文本文件:以字符为单位存储,适合保存人类可读的信息。
- 二进制文件:以字节为单位存储,适合存储图片、音频等复杂数据。
12.2 文件的打开与关闭
-
打开文件:
- 使用
fopen函数打开文件,返回一个文件指针。
FILE *fopen(const char *filename, const char *mode);
- filename:要打开的文件名,可以是相对路径或绝对路径。
- mode:文件打开模式,如 "r"、"w"、"a" 等。
- 使用
-
文件打开模式:
- "r":只读模式,文件必须存在。
- "w":写入模式,文件不存在时创建文件,存在时覆盖。
- "a":追加模式,向文件末尾写入数据。
- "rb"、"wb"、"ab":二进制文件打开模式。
-
关闭文件:
- 使用
fclose函数关闭文件,释放文件资源。
int fclose(FILE *stream);
- 使用
12.3 文件的读取操作
-
读取文件的常用函数:
- fgetc:读取一个字符。
- fgets:读取一行字符,直到遇到换行符或文件结束。
- fread:按指定大小和数量读取数据,适用于二进制文件。
- fscanf:从文件中读取格式化数据。
-
读取文件示例:
char buffer[100];
FILE *file = fopen("input.txt", "r");
if (file != NULL) {
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("%s", buffer);
}
fclose(file);
}
12.4 文件的写入操作
-
写入文件的常用函数:
- fputc:写入一个字符。
- fputs:写入一个字符串。
- fwrite:写入指定大小的数据块,适用于二进制文件。
- fprintf:将格式化数据写入文件。
-
写入文件示例:
FILE *file = fopen("output.txt", "w");
if (file != NULL) {
fprintf(file, "Hello, World!\n");
fclose(file);
}
12.5 文件指针操作
-
文件指针:
- 文件指针是指向文件的结构体,表示当前文件操作的读写位置。
-
文件位置操作:
- ftell:返回当前文件指针的位置。
- fseek:设置文件指针到指定位置。
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);-
whence 参数可取以下值:
- SEEK_SET:从文件开头开始偏移。
- SEEK_CUR:从当前指针位置偏移。
- SEEK_END:从文件末尾开始偏移。
-
rewind:将文件指针移至文件开头。
12.6 文件的错误处理
-
错误检查:
- 使用 ferror 检查文件是否发生错误。
- 使用 feof 检查文件是否读取到末尾。
int ferror(FILE *stream);
int feof(FILE *stream); -
错误处理示例:
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
if (ferror(file)) {
printf("File error occurred.\n");
} else {
printf("File does not exist.\n");
}
}
12.7 文本文件与二进制文件的区别
-
文本文件:
- 存储的数据是字符格式,可以直接读取和编辑,适用于存储可读信息(如 .txt 文件)。
- 每行结尾有换行符。
-
二进制文件:
- 存储的是原始字节数据,不可直接编辑或读取,适用于存储音频、图像、视频等非文本数据。
- 读取和写入时按字节处理,效率更高,尤其是大数据量的存储。
12.8 文件的随机访问
-
随机访问:
- C语言通过 fseek 和 ftell 支持文件的随机访问,可以根据需要直接跳到文件中的任意位置读取或写入数据。
-
随机访问示例:
FILE *file = fopen("data.dat", "rb");
if (file != NULL) {
fseek(file, 10, SEEK_SET); // 移动到文件的第10个字节
char buffer[100];
fread(buffer, sizeof(char), 50, file); // 从文件中读取50个字符
fclose(file);
}
12.9 文件的缓冲区
-
缓冲区:
- C语言对文件操作进行了缓冲,默认情况下,数据读取和写入是通过缓冲区进行的,提升了性能。
- 缓冲区可以是 行缓冲(对文本文件)或 全缓冲(对二进制文件)。
-
刷新缓冲区:
- 使用 fflush 函数可以刷新文件缓冲区,确保数据立即写入文件。
int fflush(FILE *stream);
教材学习中的问题和解决过程(先问 AI)
学习中可能遇到的问题与解答
问题1:文件指针操作中的 fseek 和 ftell 怎么使用?
-
我看了这一段文字:
"C语言通过
fseek和ftell函数支持文件的随机访问,fseek可以设置文件指针到指定位置,而ftell用来返回当前文件指针的位置。" -
有这个问题:
我不太清楚fseek和ftell这两个函数如何具体操作文件指针,尤其是在二进制文件操作时的使用。 -
我查了资料,有这些说法:
fseek(FILE *stream, long offset, int whence)用来设置文件指针的位置。whence参数可以是SEEK_SET(文件开头)、SEEK_CUR(当前指针位置)或SEEK_END(文件末尾)。ftell(FILE *stream)用来获取当前文件指针的位置,返回一个长整型值。
-
根据我的实践,我得到这些经验:
在实际操作中,我发现fseek在设置指针时,若偏移量为负值,并且whence为SEEK_CUR,会从当前指针位置倒退。例如:fseek(file, -10, SEEK_CUR)就是从当前指针位置向前10个字节。 -
但是我还是不太懂,我的困惑是:
在读取二进制文件时,如果使用fseek修改指针位置,读取的数据是否会受到缓冲区影响?如何确保精确读取二进制数据?
问题2:fread 和 fwrite 的区别
-
我看了这一段文字:
"
fread用于从文件读取数据块,fwrite用于将数据块写入文件。这两个函数适用于二进制文件。" -
有这个问题:
fread和fwrite的使用中,如何处理数据大小和数据块的结构?特别是读取和写入复杂结构体时,如何确保数据正确存储和读取? -
我查了资料,有这些说法:
fread和fwrite都使用指定的字节数进行读取和写入,通常需要提供指向目标内存位置的指针,以及要读取或写入的数据量。- 对于结构体等复杂类型,必须确保数据存储和对齐方式一致,避免因为平台或编译器差异导致的数据不一致。
-
根据我的实践,我得到这些经验:
在使用fwrite写入结构体时,确保结构体在内存中的布局与文件中的布局一致是非常重要的。我通常会使用#pragma pack(1)来避免结构体对齐问题。 -
但是我还是不太懂,我的困惑是:
在不同的操作系统上运行相同程序时,结构体的内存布局是否会发生变化?如果是这样,如何确保跨平台的二进制文件可以正常读写?
问题3:文本文件和二进制文件的区别
-
我看了这一段文字:
"文本文件以字符为单位存储,可以直接读取和编辑;二进制文件以字节为单位存储,适合存储音频、视频等非文本数据。"
-
有这个问题:
在读取文本文件时,使用fgets和fgetc比较方便,但二进制文件为什么需要使用fread和fwrite?二者有什么根本区别? -
我查了资料,有这些说法:
- 文本文件在读取时,操作系统会自动进行字符编码转换(如从 UTF-8 转换为 ASCII),并处理换行符。
- 二进制文件是逐字节读取和写入,没有这种自动转换,直接读取文件内容。
-
根据我的实践,我得到这些经验:
处理二进制文件时,我发现即使文件看起来像是文本(例如包含字符串),但实际内容可能包含非打印字符,这就导致了读取时的问题。文本文件总是以特定的字符编码存储,而二进制文件则没有任何约束。 -
但是我还是不太懂,我的困惑是:
如何判断一个文件是文本文件还是二进制文件?在实际操作中,是否可以自动区分两者?如果不能,应该如何处理?
问题4:fflush 的作用
-
我看了这一段文字:
"使用
fflush函数可以刷新文件缓冲区,确保数据立即写入文件。" -
有这个问题:
fflush用来刷新缓冲区的操作是不是在所有的文件操作中都必要?我有时候遇到文件数据没有完全写入的情况,是否和没有使用fflush有关? -
我查了资料,有这些说法:
fflush用来确保缓冲区中的数据被写入文件,在使用fputs或fprintf等函数写入数据后,通常使用fflush来确保数据被实际保存。fflush主要在文本文件中使用,在二进制文件中,通常依赖于fclose来自动刷新数据。
-
根据我的实践,我得到这些经验:
在实际的文件操作中,我发现在频繁写入数据时,使用fflush可以避免因缓冲区未及时写入导致数据丢失的情况,特别是在处理大文件时。 -
但是我还是不太懂,我的困惑是:
fflush是否会影响文件的其他部分?例如,如果一个大文件只修改其中一部分数据,使用fflush是否会导致整个文件被重新写入?
问题5:文件打开模式选择问题
-
我看了这一段文字:
"文件打开模式可以是 'r'、'w'、'a' 等,分别表示只读、写入(覆盖)和追加模式。"
-
有这个问题:
如果我希望在打开文件时能同时进行读写操作,应该选择哪种文件打开模式?我查找了相关资料,但发现有点混淆。 -
我查了资料,有这些说法:
- 使用
"r+"模式可以在只读的基础上进行写操作,前提是文件必须存在。 - 使用
"w+"模式可以进行读写操作,如果文件不存在则创建,若文件存在则清空内容。
- 使用
-
根据我的实践,我得到这些经验:
在进行文件操作时,如果既需要读取文件内容又需要修改内容,使用"r+"和"w+"会根据不同的需求有所不同。在不影响原有内容的情况下,我通常更倾向于使用"r+"模式。 -
但是我还是不太懂,我的困惑是:
如果文件是以"w+"打开的,那么文件原有的数据会被清空。我应该如何避免这种情况,或者如何确保不误操作?
基于AI的学习
我:我在学文件操作知识点,请你以苏格拉底的方式对我进行提问,一次一个问题。
GPT:好的,你能告诉我,在 C 语言中,什么是文件指针吗?
我:我不太确定,文件指针可能是指向文件的一个东西?
GPT:你的理解(回答)是什么?文件指针的作用是什么?
我:我知道它用于文件操作,像读写文件时需要用到它,但是具体的定义我不清楚。
GPT:那么,你能简要说明一下如何打开一个文件并获取文件指针吗?
我:嗯,我记得是用 fopen 函数来打开文件,但我不太确定参数是什么。
GPT:你能说一下 fopen 的常见模式以及它们的用途吗?
我:我想是“r”是只读,“w”是写入的模式,但其他的我忘了。
GPT:那么,除了“r”和“w”以外,你能想到还存在哪些其他文件打开模式?它们分别有什么作用?
我:还有“a”是追加模式,哦,还有“rb”、“wb”、“ab”是以二进制形式打开。是不是?
GPT:很接近,那么这些二进制模式的具体作用是什么,为什么需要使用它们?
我:我不太明白,可能是为了处理非文本数据?
GPT:你的理解(回答)是什么?什么情况下会使用二进制模式而不是文本模式?
我:嗯,我觉得读取图像或音频文件的时候,应该用二进制模式,因为它们不是普通文本。
GPT:很好,关于文件操作,你觉得关闭文件的重要性是什么?你如何关闭一个文件?
我:我认为关闭文件很重要,因为它能释放资源。关闭文件是用 fclose 函数。
GPT:针对我刚才问的关于文件操作知识点,你理解了吗?
我:我觉得我对文件指针、打开模式和关闭文件有了更清晰的理解,但还有些细节我不太确定。
GPT:在你对这些知识点的理解上,有什么特别需要澄清的地方吗?
我:可能是对二进制模式和文本模式的具体使用场景,需要更详细的了解。
GPT:你的理解(回答)是什么?在处理音频和图像文件时,二进制模式有什么不同于文本模式的地方?
我:我现在知道,音频和图像文件是以二进制数据存储的,文本模式不适合这些文件,因为它们会损坏数据。
GPT:我的回答结束了,请对我的回答进行评价总结。
GPT:总结来说,你对文件操作的基本概念有了初步的认识,包括文件指针、打开模式、以及关闭文件的重要性。你对二进制模式和文本模式的使用场合也有较好理解。继续深入这些知识点将进一步提高你的编程能力。很好,保持这样的学习态度,你会有所收获的!
代码调试中的问题和解决过程
-
问题1:未能成功打开文件
- 问题描述:在使用
fopen打开文件时,总是返回NULL,程序在尝试读写时崩溃。可能原因包括文件路径错误、文件权限不足或文件不存在。 - 模拟代码:
FILE *fp; fp = fopen("nonexistent_file.txt", "r"); // 尝试打开一个不存在的文件 if (fp == NULL) { printf("Error: Unable to open file.\n"); }
- 问题描述:在使用
-
问题2:写入数据时覆盖了文件内容
- 问题描述:在使用
fopen和写入模式"w"打开文件时,未意识到该模式会清空已有的文件内容。这可能导致重要数据丢失。 - 模拟代码:
FILE *fp; fp = fopen("example.txt", "w"); // 打开文件,清空其中内容 fprintf(fp, "This will delete existing content.\n"); fclose(fp);
- 问题描述:在使用
其他(感悟、思考等,可选)
在学习《C语言程序设计》第12章关于文件操作的内容过程中,我深刻体会到了文件管理在编程中的重要性。以下是我关于这一章的几点感悟和思考:
-
文件的重要性:文件是数据持久化存储的主要方式,能够有效地保存程序的输出和用户数据。理解文件操作的基本原理对于开发实际应用程序至关重要。
-
错误处理的必要性:通过实践,我意识到在打开和操作文件时,错误处理是不可忽视的环节。每次文件操作后,检查返回值并进行相应处理,可以有效避免运行时错误和数据丢失,增强程序的健壮性。
-
文本与二进制的差异:学习了文本文件和二进制文件的区别后,我明白了它们在使用时的不同场景。文本文件适合人类阅读的数据存储,而二进制文件则用于更高效的存储和处理大型数据。这让我在选择数据存储格式时更加谨慎和周全。
-
逐步调试的价值:在文件操作的调试中,我发现逐步调试通过打印调试信息来追踪程序状态是非常有效的方法。这种方法可以帮助我更快地定位问题,提高了编程效率。
-
持续学习和实践:文件操作作为一个相对复杂的主题,需要不断地通过实际编程来巩固知识。我计划在实际项目中应用这些知识,以加深对文件操作的理解和熟练度。
总的来说,这一章的学习让我对 C 语言的文件操作有了更全面的认识,增强了我的编程能力。我期待在今后的编程实践中,能够将这些知识运用自如,提升项目的质量和可靠性。
学习进度条
| 代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
|---|---|---|---|---|
| 目标 | 5000行 | 30篇 | 400小时 | |
| 第一周 | 200/200 | 2/2 | 20/20 | |
| 第二周 | 300/500 | 2/4 | 18/38 | |
| 第三周 | 500/1000 | 3/7 | 22/60 | |
| 第四周 | 300/1300 | 2/9 | 30/90 | |
| 第五周 | 400/1700 | 3/12 | 15/105 | |
| 第六周 | 500/2200 | 4/16 | 20/125 | |
| 第七周 | 500/2700 | 5/21 | 20/145 | |
| 第八周 | 400/3100 | 3/24 | 18/163 | |
| 第九周 | 300/3400 | 3/27 | 14/177 | |
| 第十周 | 400/3800 | 3/30 | 18/195 | |
| 第十一周 | 200/4000 | 0/30 | 10/205 | |
| 第十二周 | 200/4200 | 1/31 | 15/220 | |
| 第十三周 | 300/4500 | 1/32 | 15/235 |
计划学习时间:20小时
实际学习时间:15小时
改进情况:
在第十三周,我只计划了20小时的学习时间,但实际学习时间为15小时。尽管没有达到预期,但我依旧完成了一篇博客,保持了持续记录的好习惯。
在未来的学习中,我会努力提高计划的准确性,更好地评估学习任务所需的时间。经过几周的实践,我发现我的时间估算能力在逐步提高,每周的实际学习时间与预期相对接近。
我还计划在下周尝试新的学习方法,例如合理分配时间和设置小的学习目标,看看是否能提高学习效率。
浙公网安备 33010602011771号