我正在尝试使用pascal从txt文件中读取一些数据。 当我使用while循环继续执行操作而文件尚未结束时,pascal忽略while循环并继续执行程序结束。 我真的不知道为什么会发生这种情况我正在使用的文件是.txt文件,这肯定不是空的!
下的代码
program Wiki_Lezen;
{$mode objfpc}
TYPE wikiNew=RECORD
naam,omschrijving:string;
END;
var f: file of wikiNew;
var bestandsNaam:string;
var wiki:wikiNew;
var teller:integer;
begin
writeln('Geef een bestandsnaam op');
readln(bestandsNaam);
ASSIGN(f,bestandsNaam);
RESET(f);
while not EOF(f) do
begin
read(f,wiki);
writeln('wikinaam: ', wiki.naam);
writeln('Geef een omschrijving voor wiki');
readln(wiki.omschrijving);
write(f,wiki);
end;
CLOSE(f);
writeln;
writeln('Om het programma te stoppen druk op <ENTER>');
readln();
end.
答案 0 :(得分:1)
wikinew记录是512字节(两个短串,255个字符+每1个长度字节)。
你的文件是一系列512字节的记录,里面有两条短串吗?或者您是否正在尝试阅读一般文本文件?那不会奏效。 &#34;文件&#34;仅用于恒定大小的数据。
您要查找的文件类型是文本,或者如果不允许,则需要使用char文件。
答案 1 :(得分:0)
更新我已将我的示例代码和此答案的其余部分更新为
按照Marco van de Voort的评论建议使用ShortStrings,我有义务这样做。使用我更新的代码,
它创建和读取数据文件,我无法重现您的问题。
该代码将3 wiki
条记录写入文件并成功读回。
program ReadTextFileTestShortString;
{$mode objfpc} //{$H+}
uses
SysUtils;
type wikiNew = record
naam,omschrijving:string;
end;
var f : file of wikiNew;
var bestandsNaam:string;
var wiki:wikiNew;
var teller:integer;
begin
// First construct a data file name, based on the executable's name
bestandsNaam := ExtractFilePath(ParamStr(0)) + ' Wiki.Dat';
// Next, generate the file
Assign(f, bestandsNaam);
Rewrite(f);
for teller := 1 to 3 do begin
wiki.naam := 'Name' + IntToStr(teller);
wiki.omschrijving := 'Omschrijving' + IntToStr(teller);
write(f, wiki);
end;
// Now, read the file
Reset(f);
while not Eof(f) do begin
read(f, wiki);
writeln('Name: ', wiki.naam);
writeln('Description: ', wiki.omschrijving);
end;
Close(f);
readln;
end.
我将不得不留给你调查为什么你显然会有所不同 你的代码的行为。也许&#34;用户&#34;没有输入文件名 包括绝对路径,因此读取文件的不同版本 你假设的那个。
顺便说一句,这个答案的先前版本是基于这样的假设 你正在使用所谓的&#34;巨大的&#34;字符串并收到了投票。这是 合理的,但我希望现在可以删除投票。
我不明白你是如何编写代码的。作为@Tom Brunberg
在注释中注明,FPC中的字符串是引用类型,您无法声明
file of
引用类型。当我尝试编译代码时,我得到了
ReadFileTest.pas(12,26)错误:输入的文件不能包含引用计数类型。
在string
的情况下,FPC不允许包含file of
记录的原因
字符串非常明显:字符串可以包含任意序列
字符长度最大为2Gb,因此在读取文件时,RTL将无法使用
知道一个字符串字段的结束位置以及下一个字段或记录的开始。从历史上看,记录的Pascal文件总是基于记录
具有固定长度,在编译时已知,因此编写过程
文件记录的一个实例只涉及写一个图像
内存中的记录到文件中。
因此,如果要存储包含字符串字段的记录,则最直截了当
这样做的方法是使用text
文件并存储记录的各个字段
作为单独的行,例如,如下:
代码:
uses
SysUtils;
type wikiNew = record
naam,omschrijving:string;
end;
var f : Text; // declares a text file
var bestandsNaam:string;
var wiki:wikiNew;
var teller:integer;
begin
// First construct a data file name, based on the executable's name
// This is to avoid the user having to type the file name correctly
// and to ensure that the file name includes an absolute path
bestandsNaam := ExtractFilePath(ParamStr(0)) + ' Wiki.Dat';
// Next, generate the file
Assign(f, bestandsNaam);
Rewrite(f);
for teller := 1 to 3 do begin
wiki.naam := 'Name' + IntToStr(teller);
wiki.omschrijving := 'Omschrijving' + IntToStr(teller);
writeln(f, wiki.naam);
writeln(f, wiki.omschrijving);
end;
// Now, read the file
Reset(f);
while not Eof(f) do begin
readln(f, wiki.naam);
readln(f, wiki.omschrijving);
writeln('Name: ', wiki.naam);
writeln('Description: ', wiki.omschrijving);
end;
Close(f);
readln;
end.
因此,请勿尝试混合使用Pascal file of [record]
文件和Text
文件。 file of [record]
文件在正确使用后,可以正常工作,但需要基于固定长度的记录,而file of wikiNew
必然不是,因为记录定义包含string
个字段。 / p>
顺便说一下,有一个评论说明了#&#34;启动阅读&#34;可能是必要的。它不是,并且永远不需要正确编写的Pascal代码。