§8 文件
在前面的编程中,我们常需要从键盘输入数据,在屏幕显示运算结果。当需要输入的数据量较大时,调试时就必须一次次输入大量的数据,相当麻烦而且容易出错;当输出的数据很多时,屏幕上一闪而过,来不及看清,而且对输出数据无法加以利用。
Pascal提供了这样的功能:先把输入数据存到某个文件中(如txt文档),程序从文件中读入数据;程序的运算结果也可以输出到某个文件中。Pascal中有三种类型的文件:有类型文件、文本文件、无类型文件,我们主要用到文本类型的文件。
§8.1 定义路径
使用文件时,必须说明输入输出文件和程序源文件的相对位置,因此,输入输出文件最好跟程序的源文件处于同一个位置。
例如要将源程序保存到D盘的“jz0401”目录中: 先在D盘建文件夹“jz0401”;在Pascal环境中,File菜点下的“Change dir”设置路径,在弹出的对话框中输入 D:\\jz0401。
§8.2 文件的建立
输入文件必须自己建立,建立的方法有两种。
方法一: 在指定位置新建文本文档,如上例中,到D盘jz0401目录中新建一文本文档,然后打开该文档,输入内容,最后将该文档改名。
方法二:在Pascal中,用File菜单中的“new”新建一文件,输入内容后保存,注意保存时必须输入后缀名。
输入文件的后缀名可以是txt,也可以是其它自定义的类型,如“in”、“dat”等,但无论其后缀名如何写,都是可以用记事本打开(直接双击该文件后在打开方式中选择记事本),也可以在Pascal环境中用File菜单下的open(F3)打开。 输入文件的内容按程序中读入变量的顺序逐一输入,即以前在键盘输入时如何输入,在文件中也如何输入,该回车换行时也要回车换行。例如在程序中:
readln (a,b); {a、b为实型变量} readln (c); {c为字符型变量}
for i:=1 to 5 do read(S[i]); {S数组为整型} 则输入文件中的内容可以为: 3.54 7.1
h
6 22 89 1 8
§8.3 文件的使用
使用文件读入数据或输出数据时,源程序必须按如下步骤使用文件: 1.文件变量的说明: var f :text ;
2.文件变量与实际文件的连接: assign(f ,’ 文件名.后缀名 ’);
3.打开文件,做好读或写准备:
只读——Reset(f);
打开文件并作好处理准备,指针指向的第0号元素,f 必须是一个已存在的文件。 * reset 打开的文件只能读 写——Rewrite(f);
建立并打开一个新的文件(该文件名由assign赋给f ),同时作好处理准备,
把文件指针指向文件的开头,即第0号元素。以前已存在的同名文件将被覆盖。 追加——Append(f); 打开一个已存在的文件并把指针指向文件尾部,用于向文件尾部添加数据。 ...4.从文件中读出数据,或将数据写入文件 读——Read(f ,V1 ,V2 ,V3 ……);/ Readln(f ,V1 ,V2 ,V3 ……); 从文件中读出数据,依次赋给变量V1 ,V2 ,V3 …… Readln(f);
文件指针移到下一行开头
写——Write(f ,V1 ,V2 ,V3 ……);/ writeln(f ,V1 ,V2 ,V3 ……); 把变量V1 ,V2 ,V3 …… 的值依次写到文件上
Writeln(f);
把一个行结束符写到文件中,并转入下一行
5.Close(f);
关闭文件,注意:凡是进行文件操作后(无论读或写),都必须关闭文件,否则可
能丢失文件! 【例1】从文件fe01.in中读出两个正整数n和m,打印1~n的sin值到文件fe01.out,
每行m个数值。n<360,m<20 program jszx8_1;
var n,m,i,j:integer;
f1,f2:text; {f1、f2为文件变量} begin
assign (f1, ‘fe01.in’); {将文件变量f1与实际文件fe01.in联系起来} reset (f1); {以只读方式打开文件f1} read (f1,n,m); {从文件f1中读出n和m} close(f1); {关闭文件f1} assign (f2, ‘fe01.out’);
rewrite (f2); {以写方式打开文件f2,若f2未存在,则生成并打开f2 } j:=0;
for i:=1 to n do begin write(f2,sin(i)); j:=j+1;
if j mod m=0 then writeln(f2); end;
close(f2); end.
输出文件系统会自动生成,如果该路径下已有同名文件,则该同名文件会被覆盖。
【例2】编写一个加密程序,先从键盘读入源文件名和目的文件名(两个字符串),然后从
源文件读入若干段文字(只包含小写字母和空格),将其加密并输出到目的文件中。加密规则如下:
将‘a’变为‘z’,‘b’变为‘y’,……,‘y’变为‘b’,‘z’变为‘a’; 空格不变。
program jszx8_2; var s1,s2:string; cc:char; f1,f2:text; begin
readln(s1); readln(s2); {读入源文件名和目的文件名} assign (f1,s1); assign (f2,s2);
reset (f1); {以只读方式打开文件f1} rewrite (f2); {以写方式打开文件f2} repeat
read(f1,cc);
if cc=‘ ’ then write(f2, ‘ ’)
else write(f2,chr(122-(ord(cc)-97)));
{‘z’对应的ASCII码为122,‘a’对应97;详见ASCII码表}
if eoln(f1)=true then {判断是否读到行末}
begin
readln(f1); writeln(f2);
end;
until eof(f1)=true; {判断是否已读到文件末尾} close(f1); close(f2); end.
§8.2 其它相关函数
· Seek(f);
把文件指针移到文件的第n个元素,n是整数或实数表达式。注意,文件的第一个元素位置为0 。可用语句Seek(f ,filesize(f));把文件指针移到文件末尾。Filesize是一个函数,自变量是文件名,其功能是回送文件中元素的个数。因为元素是从0开始编号,所以回送的数字要比最后一个元素的编号大1。 · Erase(f);
删除文件,必须先执行Close后才能生效。 · Rename(f ,文件名); 将文件改名 · Eof(f);
这是一个布尔函数,用于判断文件结束否,当文件指针指到文件尾部,则其值为true,否则为false ,( Ctrl-Z字符是文本文件尾部标记)。 例: repeat
readln (f1,s[1],s[2],s[3]); until eof(f1); · Eoln(f);
判断行结束的布尔函数,当文件指针指向行结束符时返回true,否则返回false。 例: repeat
read (f2,c[i]); i:=i+1;
until eoln(f2); · Filepos(f);
整数函数,返回文件指针当前位置,文件的第一个元素位置为零。 · Filesize(f);
整数函数,返回文件的大小即元素个数,若为0则文件为空。 · Flush(f);
刷新文件的输出缓冲区,以保证把缓冲区的内容写到文件。
练 习
1.为例2编写一个解密程序:
先从键盘读入源文件名和目的文件名(两个字符串),然后从源文件读入若干段密文,将其解密后输出到目的文件中。 解密规则如下:
将‘a’变为‘z’,‘b’变为‘y’,……,‘y’变为‘b’,‘z’变为‘a’;空格不变。
2.金中的校园网中出现一种新计算机病毒,这种病毒高深莫测,所有查毒软件都无能为力。经jzoi小组研究,发现被这种病毒感染的文件的第三行为一串字符“ I am a lovely worm. ”,现需要对若干个文件进行查毒,请你帮忙编写这个查毒程序。
这需检查的文件的文件名已事先存入一个文件 fname.txt,每行一个文件;查毒的结果请存入fresult.out,每行对应fname.txt中的文件,若该文件已被感染,则输出‘worm!’,否则输出‘ok’。