(编辑完成后,我发现你的代码现在编译了FPC中没有错误,所以我很高兴你自己设法修复了错误)
由于这显然是课程作业,我不打算为你修复你的代码,无论如何 即便如此,我担心你这是完全错误的。
基本上,您的代码的主要问题是您正在尝试控制在逐个字符地读取源文件时发生的情况。坦率地说,这是一种试图做到这一点的绝望方式,因为它使得执行流程不必要地变得复杂并且充斥着ifs,buts和loop。它还要求您在任何给定步骤中记录您尝试执行的操作,并且生成的代码本身就是如此 的 不 强> 自我记录 - 想象一下,如果你在六个月内回到你的代码中,你能一眼就看出它是如何工作的以及它的作用吗?我证明不能亲自。
你需要以不同的方式打破任务。而不是自下而上地分析问题(“如果我接下来读这个字符,那么我接下来需要做的是......”)从上到下做:尽管你的输入文件是 file of char ,它包含一系列字符串,用a分隔 / 字符,最后由一个终止 $ (但这个终结者并不重要)。所以你需要做的是逐个阅读这些字符串;一旦你有一个,检查它是否是你正在寻找的那个:如果是的话。然而,你需要处理它,否则读取下一个,直到你到达文件的末尾。
file of char
/
$
成功阅读其中一个书籍字符串后,您可以将其拆分为由其组成的各个字段。执行此拆分最有用的功能可能是 Copy ,它允许您从字符串中提取子字符串 - 在FPC帮助中查找它。我已经包含了功能 ExtractTitle 和 ExtractPreamble 它显示了你需要做什么来编写类似的函数来提取T / R代码和连字符后面的数字代码。顺便说一下,如果你将来需要问一个类似的q,如果你在文件中包含各种字段的布局和含义的描述,将会非常有用。
Copy
ExtractTitle
ExtractPreamble
所以,我要告诉你的是如何阅读你的系列字符串 S.Txt 通过逐个字符地构建它们。在下面的代码中,我使用函数执行此操作 GetNextBook 我希望这是合理的不言自明的。代码在a中使用此函数 while 循环来填补 BookRecord 字符串变量。然后,它只是写 BookRecord 到控制台。当然,你的代码应该做的是处理 BookRecord 内容以查看它是否是您正在寻找的内容,然后执行您的任务的剩余部分。
S.Txt
GetNextBook
while
BookRecord
我希望您会同意下面的代码更清晰,更短,并且将来比您的q中的代码更容易扩展。他们以这种方式构建程序的关键是将程序的任务分解为一系列功能和程序,每个功能和程序执行一个子任务。以这种方式编写程序可以更容易地“重新连接”程序以改变它的功能,而无需重写函数/过程的内部。
program fileofcharproject; uses crt; const sContents = '02022013Rto kill a mockingbird-1301/02012014Tpeter pan-1001/02032013Thowto-2301/02012012Tmaze runner-1001/02012012Tmaze runner-1001/02012012Tmaze runner-1001/$'; InputFileName = 'C:\Users\MA\Documents\S.Txt'; OutputFileName = 'C:\Users\MA\Documents\Sal.Txt'; type CharFile = File of Char; // this is to permit a file of char to be used // as a parameter to a function/procedure function GetNextBook(var S : CharFile) : String; var InputChar : Char; begin Result := ''; InputChar := Chr(0); while not Eof(S) do begin Read(S, InputChar); // next, check that the char we've read is not a '/' // if it is a '/' then exit this while loop if (InputChar <> '/') then Result := Result + InputChar else Break; end; end; function ExtractBookTitle(BookRecord : String) : String; var p : Integer; begin Result := Copy(BookRecord, 10, Length(BookRecord)); p := Pos('-', Result); if p > 0 then Result := Copy(Result, 1, p - 1); end; procedure AddToOutputFile(var OutputFile : CharFile; BookRecord : String); var i : Integer; begin for i := 1 to Length(BookRecord) do write(OutputFile, BookRecord[i]); write(OutputFile, '/'); end; function ExtractPreamble(BookRecord : String) : String; begin Result := Copy(BookRecord, 1, 8); end; function TitleMatches(PartialTitle, BookRecord : String) : Boolean; begin Result := Pos(PartialTitle, ExtractBookTitle(BookRecord)) > 0; end; var i : Integer; //byte; s,sal: file of char; l1,l2: char; InputChar : Char; BookFound : Boolean; cs,cn,cl: integer; pn,ps,tot: integer; Contents : String; BookRecord : String; PartialTitle : String; begin // First, create S.Txt so we don't have to make any assumptions about // its contents Contents := sContents; Assign(s, InputFileName); Rewrite(s); for i := 1 to Length(Contents) do begin write(s, Contents[i]); // writes the i'th character of Contents to the file end; Close(s); cs:=0; cn:=0; i:=0; cl:=0; // Open the input file Assign (s, InputFileName); {$I-} Reset (s); {$I+} if IOResult <> 0 then begin writeln('Error'); halt(2); end; // Open the output file Assign (sal, OutputFileName); {$I-} Rewrite (sal); IOResult; {$I+} if IOResult <> 0 then halt(2); // the following reads the BookRecords one-by-one and copies // any of them which match the partial title to sal.txt writeln('Enter part of a book title, followed by [Enter]'); readln(PartialTitle); while not Eof(s) do begin BookRecord := GetNextBook(S); writeln(BookRecord); writeln('Preamble : ', ExtractPreamble(BookRecord)); writeln('Title : ', ExtractBookTitle(BookRecord)); if TitleMatches(PartialTitle, BookRecord) then AddToOutputFile(sal, BookRecord); end; // add file '$' to sal.txt write(sal, '$'); Close(sal); Close(s); writeln('Done, press any key'); readln; end.