第七章文件类型7.1文件类型7.1文件类型之前,我们把数据放在变量或者数组中。它的缺点是我们无法永久保存数据,因为关机后RAM(随机存取存储器)中的所有数据都会丢失。在这一章中,我们学习将数据或运算的最终结果放入一个文件中,从而实现永久存储或便于重复读取和使用。Turbo Pascal中引入了文件变量的概念,也就是说,要操作实际的外部文件,首先要定义一个文件变量与之关联,并定义这个文件变量的文件类型。文件类型清楚地表明了相关外部文件中数据的存储格式。Turbo Pascal中的文件类型有:类型文件、文本文件和非类型文件。文本文件和非类型化文件是系统定义的标准文件类型,编写程序时可以直接使用它们的文件类型标识符(即文本和文件)。在Turbo Pascal中,赋值标准过程用于建立文件变量和实际外部文件之间的联系。对于现有文件,可以通过重置标准流程或追加标准流程打开。当通过reset打开文件时,指针指向第一个数据,而当通过append打开文件时,指针指向最后一个数据的后面,所以append适用于向文件追加数据。对于不存在的文件,您可以创建一个新文件,并使用重写标准程序打开它。在我们处理完文件后,记得用close标准进程关闭文件,否则数据可能仍然留在磁盘缓冲区中,并没有真正写入文件。应特别注意由文本文件类型定义的文件。当通过重置标准进程打开文件时,只能进行读取操作,不能向文件中写入数据。目前中学生信息科学(计算机)奥林匹克竞赛主要使用文本文件读写数据,所以本章只介绍文本文件的使用。7.2文本文件及其应用7.2.1文本文件所谓文本文件,是指其数据以文本文件类型指定的格式存储的文件。在Turbo Pascal中,文本文件类型是系统定义的标准文件类型,我们在编写程序时可以直接使用文本文件类型标识符。文本文件是应用最广泛的文件,大多数程序的输入输出都是文本文件。文本文件中的每个组成部分都是一个字符,以ASCII码存储。多个ASCII字符组成一个文本行。行由行终止符(CR/LF)分隔。行结束符由两个特殊的控制字符组成,分别是回车(在ASCII表中表示为CR或#13,代码值为13)和换行(在ASCII表中表示为LF或#10,代码值为10)。当我们用文本编辑器打开一个文本文件时,行结束符是不可见的。二是通过write的标准流程输出chr(13)+chr(10)的表达式。第三种方法使用标准的写入过程来输出#13#10。行结束符可以通过标准函数eoln(x)来检测,其中x是一个文件变量,当返回结果为true时,行结束。每个文件的末尾都应该有一个文件终止符,在关闭文件的时候会由各种文件编辑器自动写入。它可以用封闭的标准过程写在程序中。在DOS模式下建立copy con[盘符][路径][文件名]的命令格式时,编写文件终止符的方法是按CTRL+Z,文件的结束可以用标准函数eof(x)来检测,其中x是文件变量,当返回结果为真时,文件结束。在Turbo Pascal中,计算机中已经定义了两个特殊的文件变量,即输入和输出,它们的文件类型都是文本文件类型。输入变量的外部接触设备是键盘,输出变量的外部接触设备是显示器,即把键盘输入和显示器输出当作两个文本文件。这两个特殊的文本文件在运行程序时会自动打开,在程序结束时会自动关闭。因为程序中经常用到输入和输出,所以文件变量标识符input和output在用来操作显示器和键盘时经常被省略,这是我们过去写过的。比如eof相当于eof(输入);Eoln相当于eoln(输入);Read(a,b,c)等价于read(input,a,b,c);Readln(a,b,c)等价于readln(input,a,b,c);Readln等价于readln(input)writeln(a,b,c)等价于writeln(output,a,b,c);Writeln等效于writeln(output)示例7.1。体验输入输出本色,无遗漏。程序rzy 7 _ 1;var c:整数;开始改为(c);writeln(c);结束。程序rzy 7 _ 1;var c:整数;输入,输出:文本;等效程序效果begin assign (input,' ');赋值(输出,' ');复位(输入);重写(输出);注意:“”是一个空字符串,对应于键盘或监视器。输入和输出是由系统定义的文本文件变量,系统可以省略对它们的所有描述。read(输入,c);writeln(输出,c);关闭(输入);关闭(输出);结束。运行程序,输入数据:AB?0?7 CDE?0?7输出结果:65 66 13 10 67描述:C [1],C [2]和C [5]分别存储在对应的字符A,B和C中,但行结束符#13保存在C[3]和C[4]中。d和e字符实际上并没有被读入。这种情况经常发生在从文本文件中读取字符数据时,我们在编程时要特别注意!这个例子说明了行终止符(CR/LF)的存在。例7.2体验行终止符的存在。程序rzy 7 _ 2;var i:整数;c:数组[1..5]的charbegin for i:=1到5 do read(c[I]);for i:=1到5 do write(ord(c[i]),' ');结束。例7.3是例7.2的改进。在字符模式下读取行结束符但不想读入数组的方法是使用eoln函数。运行程序,输入数据:AB?0?7 CD?0?7 E F?0?7输出结果:65 66 67 68 69描述:C [1],C [2],C [3],C [4],C [5]分别存储了字符A,B,C,D,E,字符F没有读入,因为这个程序只读入5个数。本程序实现不读取行终止符的方法是:使用eoln函数判断当前位置是否有行终止符,如果有,使用readln标准进程将该行未被读取的数据全部扔掉。其实readln(x,y)等价于read(x,y);readln这两句话的组合。现在对read和readln的用法有更深的理解了吗?程序rzy 7 _ 3;var i:整数;c:数组[1..5]的charbegin I:= 1;而我& lt= 5 do if eoln then readln else begin read(c[I]);I:= I+1;结束;for i:=1到5 do write(ord(c[i]),' ');结束。例7.4试编程将1到100的数字写入文件rzy7_4.txt,要求数字之间用空格隔开,每行10个数字。描述:(1)outfile是一个文件变量,定义为文本文件类型。outfile变量通过标准的赋值过程与当前目录中的rzy7_4.txt文件相关联。如果文件放在c:\tp7\program的目录下,应该改成:Assign (outfile,' c: \ tp7 \ program)。(2)rewrite(outfile)告诉系统每次运行程序时创建一个新文件。(3)写(outfile,I,' ');函数是将I值和一个空格字符写入outfile对应的文件。(4)4)writeln(outfile)的作用是在outfile对应的文件中写入一个行结束符。(5)5)关闭(outfile)的作用是关闭文件。程序rzy 7 _ 4;var outfile:text;I:整数;begin assign(outfile,' rzy 7 _ 4 . txt ');重写(outfile);对于i:=1到100,开始写(outfile,I,' ');如果(i mod 10)=0那么writeln(outfile);结束;关闭(输出文件);结束。Turbo Pascal编辑器也是一个文本文件编辑器。我们可以使用这个编辑器打开数据文件RY7 _ 4。上面程序生成的txt。文本文件习惯使用扩展名。txt。在Turbo Pascal编辑器中尝试【文件】的【打开】,打开当前目录下的rzy7_4.txt文件。注意输入文件的全名,观察程序生成的数据是否合理。注意:用户自定义的inputfile是文本文件类型的文件变量,例7.4中的outfile都是用户自定义的文件变量标识符。自定义文件变量的名称也应尽可能包含一定的实际意义,以便于记忆和减少错误。例7.5试用程序从当前目录下的数据文件rzy7_4.txt中读取数据并显示在屏幕上,要求每行显示10个数字。程序rzy 7 _ 5;var x,k:整数;inputfile:文本;Begin描述:(1) Assign (inputfile,' RY7 _ 4.txt ')用于将inputfile变量与外部文件关联起来。(2)2)reset(input file)的作用是打开文件。(3)eof(inputfile)用于判断当前位置是否是文件的结束位置。(4)read(inputfile,x)的作用是从input file指定的文件中读入一个数到x中。(5)write(x,'')用于向屏幕输出数字和空格字符。(6)6)关闭(inputfile)的作用是关闭与inputfile连接的文件。(7)注意:除了键盘和屏幕对应的文件变量(input,output)外,什么都不能保存。赋值(inputfile,' rzy 7 _ 4 . txt ');重置(输入文件);k:= 0;而不是eof(inputfile)和(k & lt100)开始读取(inputfile,x);写(x,' ');k:= k+1;如果(k mod 10)=0那么writeln结束;关闭(输入文件);结束。如果您想了解更多关于标准程序赋值、关闭和函数eoln和eof的信息,请阅读Turbo Pascal编辑器中的帮助。7.2.2将数据写入文本文件将数据写入文本文件的方法非常简单。和写屏幕从上到下,从左到右的方法一样。不同的是指定文件变量,并记住在写入所有数据后关闭文件。例7.6生成文件rzy7_6.txt,要求第一行总人数,第二行开头记录姓名、语文、数学、英语、总分、平均分,数据之间要用逗号隔开。例子如下:运行程序的输入格式如下:输入人数= 3否:1姓名=李明中文、数学、英语:70 75 60否:2姓名= rzhiyuan中文、数学、英语:80 76 70否:3姓名= kuyuanchinese、数学、英语:68 76 55尝试用文本文件编辑器打开rzy7_6.txt。内容如下:3黎明,70,75,60,205,68.3仁智元,80,76,70,226,75。76,55,199,66.3说明:也可以在dos模式下执行DOS命令:键入rzy7_6.txt查看内容。
描述:(1)将stfile变量定义为文本文件类型。Name存储名称,最长的字符串类型是16位数字。如果使用字符串,则字符串长度为255位。c,m,e,t,av分别对应语文,数学,英语,总分,平均分。(2)assign建立stfile变量和外部文件之间的连接。重写(stfile)意味着每次都会创建一个新文件。程序rzy 7 _ 6;var ST file:text;名称:string[16];I,n,c,m,e,t:整数;av:真实;begin assign(stfile,' rzy 7 _ 6 . txt ');重写(ST file);注意:(3)在3)write语句中,如果没有指定stfile,将发送到屏幕(输出)。(4) writeln(stfile,n);的作用相当于write(stfile,n);writeln(stfile)语句的功能,其中writeln(stfile)实现了输出行结束符的功能。写('输入人民号码= ');readln(n);writeln(stfile,n);for I:= 1 to n do begin writeln(' no:',I);写(' name = ');readln(姓名);(5)因为在输出数据中需要逗号作为分隔符,所以在这里可以将逗号作为字符输出。写('语文、数学、英语:');readln(c,m,e);t:= c+m+e;av:= t/3;writeln(stfile,name,',',c,',',m,',',e,',',t,',',av:5:1);结束;关闭(ST file);结束。7.2.3读取文本文件数据的应用由于Turbo Pascal的read或readln的标准流程,对读取格式有严格的要求。也就是要求数字之间用空格隔开。另外,阅读时不要有任何误解。例如:readln(c,X),其中c为字符串类型,X为数值(实数或整数)类型,当输入数据为rzy 25.6时,计算机会将其误解为c:='rzy 25.6 '并要求X的另一个数值.或者c为string[3],提供数据rzy 25.6可以通过,虽然可以使c:='rzy '和x:=25.6,但当改为提供数据r 25.6时,会将其误解为c:='r因此,当一个文件中的数值型数据和字符串型数据混合为数据线或者数据被非空白字符分隔时,我们只能将整行作为字符串读取,然后使用与字符处理相关的标准函数或流程将数据从字符串中分离出来。例7.7:非标准输入格式的例子。请使用Pascal编辑器创建以下内容的数据文件,然后运行程序从文件中读取数据并显示在屏幕上。其中数据文件名被改变以在运行程序时被提供。rzy7_7.txt文件的内容和格式如下:rzy,c112,65,76mxf,g 12,85,78huangjian,g212,87,77运行程序如下(假设输出文件为rzy7 _ 7.txt):输入输入文件名:rzy 7 _ 7 . txtrzy c 17
参考程序如下:程序rzy7 _ 7定义过程processing专用于处理一行字符串。从题目知道数的格式是2串2整数每行。所以分别保存了st1,st2,x,y的定义。e用于保存逗号位置。St用作临时变量。var infile:text;s,filename:string;过程processing(s:字符串);var st1,st2,ST:string;x,y,e,代码:整数;Begin将数据从字符串处理中分离出来:(1)查找逗号位置;(2)截取逗号前字符串;(3)从字符串中删除截取的子串和逗号。重复以上过程即可。对于整数部分,将截断的或最后剩余的子串转换成数值就足够了,代码作为返回是转换成功的标志。如果返回code=0,则转换成功。关于该功能的使用,请参考帮助描述或本书的1.2.7节。如果s & gt‘’然后begin e:= pos(‘,’,s);st1:=copy(s,1,e-1);删除(s,1,e);e:=pos(',',s);st2:=copy(s,1,e-1);删除(s,1,e);e:=pos(',',s);st:=copy(s,1,e-1);删除(s,1,e);val(st,x,code);val(s,y,code);writeln(st1,' ',st2,' ',x,' ',y);结束;结束;提供的数据文件可能不存在。我该怎么办?解决方法:在复位或重写前添加编译开关{$I-},用于使所有接口(I/O)错误不提示或中断程序执行。在将编译开关重新设置为{$I+}之前,尝试重置或重写该文件。Turbo Pascal定义了一个不带参数的标准函数ioresult,可以返回接口错误,返回值为0表示读写成功。尝试咨询帮助。这个程序将一行作为一个字符串读取,然后将数据分解为字符串s。