读取文件有固定的模式:打开文件,一直读到文件结尾,关闭文件。循环不知道有多少行,所以每次都问一个问题:“文件读完了吗?”
本课属于搜索、排序与文件。它用到重复结构与数组的循环技能,以及读取记录中处理一行数据的方法。具体的语句写法,请查看你所考年份的 Cambridge 伪代码指南。
这个模式是什么样的?
OPENFILE "Marks.txt" FOR READ
WHILE NOT EOF("Marks.txt")
READFILE "Marks.txt", Mark
...use Mark...
ENDWHILE
CLOSEFILE "Marks.txt"
判断放在循环开头,所以每次读取之前都会检查。读取放在循环体里面,因为每次读取都会移到下一行。
例题
一个虚构文件 Marks.txt 有三行,每行是一个整数:12、7、20。下面的程序把它们加起来并求平均数。
Total ← 0
Count ← 0
OPENFILE "Marks.txt" FOR READ
WHILE NOT EOF("Marks.txt")
READFILE "Marks.txt", Mark
Total ← Total + Mark
Count ← Count + 1
ENDWHILE
CLOSEFILE "Marks.txt"
OUTPUT Total / Count
| 步骤 | EOF? | Mark | Total | Count |
|---|---|---|---|---|
| 循环前 | 0 | 0 | ||
| 判断 1 | FALSE | 0 | 0 | |
| 循环体 1 之后 | 12 | 12 | 1 | |
| 判断 2 | FALSE | 12 | 1 | |
| 循环体 2 之后 | 7 | 19 | 2 | |
| 判断 3 | FALSE | 19 | 2 | |
| 循环体 3 之后 | 20 | 39 | 3 | |
| 判断 4 | TRUE | 39 | 3 |
判断 4 时文件已没有内容,循环结束。输出是 39 / 3 = 13。核对:12 + 7 + 20 = 39,39 除以 3 等于 13。
要留意的错误
一位学生忘了读取:
WHILE NOT EOF("Marks.txt")
Total ← Total + Mark
Count ← Count + 1
ENDWHILE
循环里没有任何东西读取一行,所以文件位置永远不动。EOF 一直是 FALSE,循环永远不会结束。而且 Mark 从来没有从文件里得到过值。
改正方法是把 READFILE 放进循环体,并且放在使用 Mark 之前。追踪文件循环时,永远问:“这个循环体里有什么会让判断最终变成真?”受限伪代码追踪训练器会在安全上限处停住这样的循环,并显示从未改变的变量,错误就一目了然。
第二个失误是把 CLOSEFILE 放进循环。第一轮会关闭文件,第二轮就要从已关闭的文件读取。
自我检测
1. 文件有 4、9、6 三行。用上面的程序,最后 Total 和 Count 是多少?
显示答案
4 + 9 + 6 = 19,循环体每行执行一次。Total = 19,Count = 3。
2. 一个文件有五行。循环体执行几次?EOF 判断被计算几次?
显示答案
循环体执行 5 次。EOF 判断被计算 6 次:五次为假,最后一次为真。
3. CLOSEFILE 应该放在哪里?为什么?
显示答案
放在 ENDWHILE 之后。 它在所有读取结束后执行一次。放在循环里,第一次读取之后文件就被关闭了。
接下来学什么
本模块最后一课讲如何用空数据和重复数据检查算法。它也会重用这个文件循环,因为空文件会让 Count 变成零。
如果文件题因为顺序上的小失误而丢分,我们的老师可以通过一对一线上计算机科学补习陪你改进。