=j;
t:
=a[i];a[i]:
=a[p];a[p]:
=t;
end;
assign(f2,'datasort.out');{关联文件变量f2到输出文件datasort.out}
rewrite(f2);{以新建写文件的方式打开文件f2}
fori:
=1tondo
begin
write(f2,a[i]:
5);{将数组中的数依次写到文件里}
ifimod10=0thenwriteln(f2);{每写10个数换一行}
end;
close(f2);{关闭文件}
end.
程序运行后,用记事本程序打开datasort.out文件,可以看到排列好的数据如图4.2所示。
图4.2 排序后的数据文件内容
【相关知识】
1.pascal程序中读文件的5个步骤
在Pascal程序中读入也要经历5个步骤,即:
定义文件变量、关联磁盘文件、读准备、读数据、关闭文件变量。
定义文件变量、关联磁盘文件、关闭文件变量等几步和写文件操作类似,这里就不再赘述了。
读准备是在读数据之前,先以读方式,复位文件指针,命令格式是reset(文件变量)。
读数据时,就使用读语句read和readln语句。
和写文件数据一样,读数据时也要指定从那个文件变量中读入数据。
如:
read(f,s)或readln(file1,a(5),a(6))
即从文件f中读入数据,赋值给变量s;从文件file1中读入两个数据,赋值给数组变量a(5)、a(6)。
以读文件方式时打开文件时,实际上有一个文件指针指向第1个数据,读完一个数据后,指针自动指向下一个数据,当程序中再有读数据操作时,将读入指针所指的数据。
碰到readln语句时,读完readln语句所需数据后,文件指针自动换行,指向下一行的第1个数据。
2.与文本文件相关的函数:
与文本文件相关的函数有两个,即eof(f)和eoln(f),它们的含义是:
(1)eof(f)—布尔函数,用于判断文件结束否。
其中f是文件变量,函数的返回结果为true时,表示到达文件尾,反之则未到文件尾。
eof是endoffile的缩写。
(2)eoln(f)—布尔函数,用于判断行结束否。
其中f是文件变量,函数的返回结果为true时,表示到达本行结尾,反之则未到行尾。
eoln是endofline的缩写。
【同步练习】
1.现有两个已经按从小到大排好序的整数文件f1和f2,请编写程序将f1和f2合并成一个文件f12,使得合并后的文件也是按从小到大排好序的。
问题分析:
解决本题需要处理好以下几个方面的问题。
①本文题涉及到同时对三个文件的操作,同时从f1和f2中读取数据,再向f3中写数据。
只要思路清晰,文件的读写部分难度不大。
②由于数据量不定,读取数据用while循环,循环的条件由eof(f)函数来控制。
③合并的算法可以采用如下思路:
先从f1和f2各读一个数a1、a2,比较大小,将小的(假如a2小)写入f3;接着再在f2中读一个数,跟a1比,小的写入f3,依此类推,直到某个文件中的数读完,再将另外一个文件中剩下的数依次写入f3。
这个算法就好像两个已经按高矮排好队的队列合并成一个新队列一样。
请你想象一下就会明白这个算法的思路了。
2.编写一程序,计算英文文章文本文件中,字母e出现了多少次。
3.编写一程序,统计一个文本文件f中共有多少行和多少字符。
4.编写程序从磁盘上读取一个由100个实数组成的实型数据文件(indata.dat),以此文件中所有大于平均值的实数建立一个名为“above.dat”的文件,其余的建立一个名为“rest.dat”的文件。
第3节利用文件测试程序
【问题描述】
某学习小组有10人,参加某次测验,考核6门功课,统计每人的总分及各门的平均分,将原始数据及结果数据放入文本文件中。
【问题分析】
本文题的程序设计部分所涉及的知识都是前面学习过的文件知识,这里主要是讨论如何编写制作测试数据来检验程序的正确性。
利用Windows的“记事本”程序建立原始数据文件textin.dat存贮在磁盘中,其内容如下:
106
1788967909867
2909386848693
3938578897898
4678976679874
5837592788974
6765789847371
7819374767886
8688391837889
9637183947895
10789990808670
程序读入原始数据文件,求每人的总分及各门的平均分;同时建立结果数据文件,文件名为textout.dat。
【程序实现】
programp4_3(input,output);
var
f:
text;
i,j,n,m,s:
integer;
data:
array[1..11,0..7]ofinteger;
p:
array[1..6]ofinteger;
begin
assign(f,'textin.dat');{从文本文件中读取数据}
reset(f);
read(f,n);readln(f,m);
fori:
=1tondo
forj:
=0tomdo
read(f,data[i,j]);
close(f);
fillchar(p,sizeof(p),0);{将数组p中元素全部赋值为0}
fori:
=1tondo
begin
s:
=0;
forj:
=1tomdo{求每人总分,各科总分}
begin
s:
=s+data[i,j];
p[j]:
=p[j]+data[i,j];
end;
data[i,m+1]:
=s;
end;
fori:
=1tondo {显示输出数据}
begin
forj:
=0tom+1do
write(data[i,j]:
4);
writeln;
end;
write('');
forj:
=1tomdo{求各科平均分}
begin
p[j]:
=p[j]divn;
write(p[j]:
4);
end;
writeln;
assign(f,'textout.dat');{将数据写入文件}
rewrite(f);
fori:
=1tondo
begin
forj:
=0tom+1do
write(f,data[i,j]:
4);
writeln(f);
end;
write(f,'');
forj:
=1tomdo
write(f,p[j]:
4);
writeln(f);
close(f);
end.
【相关知识】
1.手工测试的问题
实际上,我们在未使用文件来编写程序时,通过read语句输入数据时,可以在运行过程中换用不同的数据来测试程序,但是有些程序往往无法手工进行测试,这是由于有时数据量较大时,手工输入测试费时费力,而且容易出错,像本例中要测试一组数据要输入60个数据,非常麻烦;还有的时候,由于数据量太大,根本无法手工完成测试数据,比如,本章第1课中测试一组数据要500个数据,手工测试几乎不可能。
因此,必须使用文件来测试程序
2.测试文件的制作
程序所需测试数据文件的制作一般采用两种方法,一是利用“记事本”程序手工编写的方法,另一种是利用程序来自动生成。
本章第2课问题中测试一组数据要500个随机数,这种情况往往需要另外编写一段程序来自动生成。
这里我们重点讨论第1种方法。
“记事本”程序是Windows自带的文本文件编辑程序,利用它可以快速的编写我们想要的数据文件。
具体的操作步骤是:
①按键盘上空格键两边的“Windows”键,切换回桌面。
②进入需要建立测试数据的文件夹,如“2005pas”,按如错误!
未找到引用源。
所示操作,使Windows显示文件的扩展名。
图4.3 显示文件的扩展名
③在“2005pas”文件夹中,按如图4.4所示操作,建立文本文件,并改名为“textin.dat”。
图4.4 建立文本文件
④新建的文件默认文件名为“新建文本文档.txt”,右击该文件,选择“重命名”菜单,按如所示操作,将文件改名为程序所需的测试文件名,如“textin.dat”。
在出现“可能会导致文件不可用”提示时,确认更改。
图4.5 修改文件扩展名
⑤按住键盘上的Shift(上档)键不放,右击该文件,选择“打开方式”菜单命令,在弹出的“打开方式”对话框中按如图4.6A所示操作,将该文件关联到“记事本”程序。
A调整打开方式B输入数据
图4.6 制作测试文本文件
⑥双击该文件,在打开的记事本界面中输入测试数据,最后选择“文件”→“保存”菜单命令保存。
⑦单击桌面底端任务栏上的freepascal程序,修改好程序中调用测试文件的路径和文件名,运行程序,测试程序的正确性。
【同步练习】
1.有两个文本文件name.in和age.in,两个文件的行数相同,其中第1个文件中每行是人名,第2个文件中每行是年龄。
编写一程序生成一个新的文件info.out,它的每一行由name.in人名和age.in年龄的对应行数据组成。
利用记事本事先制作好name.in和age.in这两个测试文件