记录(record)是一组相关的项目,每个项目是一个字段(field)。当文件把记录存成一行行文本时,程序必须把每一行切回字段,而且不能让边界移位;如果需要计算,还要把文本里的数字转成数值。
本课属于搜索、排序与文件。这里的数据都是虚构的,下一课处理文件结尾会讲如何读取很多这样的行。
一行可以怎样拆成字段?
常见的设计有两种。
分隔符字段。 用逗号等标记隔开字段。Aina,10B,72 有两个逗号,所以有三个字段。
固定宽度字段。 每个字段总是占用相同数量的字符,不足的部分用空格或零补齐。程序是数字符,而不是找标记。
例题:分隔符
这一行是 Aina,10B,72,存放姓名、班级和分数。用 Python:
line = "Aina,10B,72"
fields = line.split(",")
name = fields[0]
cls = fields[1]
score = int(fields[2])
print(name, cls, score + 5)
line.split(",") 得到 ["Aina", "10B", "72"]。Python 从 0 开始计位置,所以姓名是 fields[0],分数是 fields[2]。
分数以文本 "72" 的形式到来,所以用 int 转成数字 72。接着 score + 5 是 77,输出为 Aina 10B 77。
Cambridge 风格的伪代码计数方式不同,也有自己的字符串函数,所以请查看你所考年份最新的伪代码指南。关于边界的思路是一样的。
例题:固定宽度
这一行是 Aina 10B072,姓名字段 6 个字符,班级字段 3 个,分数字段 3 个。
| 字段 | 字符位置 | 值 |
|---|---|---|
| 姓名 | 1 到 6 | Aina (名字加两个空格) |
| 班级 | 7 到 9 | 10B |
| 分数 | 10 到 12 | 072,即数字 72 |
核对数量:Aina 4 个字符加 2 个空格是 6,再加 10B 是 9,再加 072 是 12。在伪代码中,MID(Line, 7, 3) 返回从位置 7 开始的 3 个字符,即 10B。分数字段 MID(Line, 10, 3) 返回 072。
要留意的错误
一位学生把文件里的两个分数当成文本来比较:
"9"比"72"大吗?
作为文本,比较是逐个字符进行的:"9" 对 "7"。字符 9 排在 7 之后,所以文本 "9" 被判为更大。作为数字,9 显然小于 72。
改正方法是在比较或相加之前,先把字段转成数字。追踪时,在每个字段旁写上数据类型。第二个边界错误是逗号文件里出现 Tan, Mei 这样的姓名:拆分得到四个字段而不是三个,班级就落到了分数的位置。
自我检测
1. 在逗号处拆分 Zara,11A,64。第三个字段是什么?它加 6 是多少?
显示答案
字段:Zara、11A、64。第三个字段是 "64",转成数字 64。然后 64 + 6 = 70。
2. 固定宽度的行 Omar 09C055 宽度为 6、3、3。写出每个字段。
显示答案
字符 1 到 6 是 Omar 。字符 7 到 9 是 09C。字符 10 到 12 是 055,即数字 55。
3. 行 Lee, Ann,10C,81 在逗号处拆分。得到几个字段?哪里出了问题?
显示答案
三个逗号得到四个字段:Lee、 Ann、10C、81。分隔符出现在姓名里面,所以后面每个字段都错位了一格。
接下来学什么
字段掌握之后,继续学读取整个文件直到结尾。安全 Python 推理沙盒可以让你试一试上面那样的拆分,看每个字段被打印出来。
如果记录和类型转换在新的行上仍然不顺,我们的老师可以通过一对一线上计算机科学补习陪你做更多例子。