gpt4 book ai didi

delphi - 在 Pascal 中将文本文件中的字符串读入数组

转载 作者:行者123 更新时间:2023-12-02 03:40:27 24 4
gpt4 key购买 nike

通过这个程序,我试图读取一个文件并将其随机打印到控制台。我想知道是否必须使用数组。例如,我可以将字符串分配到一个数组中,然后从数组中随机打印。但是,我不确定如何解决这个问题。另一个问题是,我当前的程序没有从我的文件中读取第一行。我有一个文本文件 text.txt 其中包含

1. ABC
2. ABC
...
6. ABC

下面是我的代码。

type
arr = record
end;

var
x: text;
s: string;
SpacePos: word;
myArray: array of arr;
i: byte;

begin
Assign(x, 'text.txt');
reset(x);
readln(x, s);
SetLength(myArray, 0);
while not eof(x) do
begin
SetLength(myArray, Length(myArray) + 1);
readln(x, s);
WriteLn(s);
end;
end.

请告诉我如何解决这个问题!

最佳答案

您的程序存在一些问题。

  1. 您的第一个Readln将文件的第一行读入 s ,但您根本不使用该值。它丢失了。第一次做Readln在循环中,您将获得文件的第二行(您可以使用 Writeln 将其打印到控制台)。

  2. 您的arr在这种情况下(并且在大多数情况下),记录类型完全没有意义,因为它是没有任何成员的记录。它无法存储任何数据,因为它没有成员。

  3. 在循环中,您扩展数组的长度,一次一项。但是您没有将新项目的值设置为任何值,因此您这样做是徒劳的。 (并且,由于上一点,在任何情况下都不需要设置任何值:数组的元素是不能包含任何数据的空记录。)

  4. 每次增加动态数组的长度为 very bad practice ,因为它可能每次都会导致新的堆分配。每次都可能需要将整个现有数组复制到计算机内存中的新位置。

  5. 循环的内容似乎试图做两件事:将当前行保存在数组中,并将其打印到控制台。我认为后者仅用于调试?

  6. 旧式 Pascal I/O( textAssignReset )已过时。它不是线程安全的,可能很慢,不能很好地处理 Unicode,等等。它曾在 90 年代使用,但现在不应该使用。相反,请使用 RTL 提供的设施。 (例如,在 Delphi 中,您可以使用 TStringListIOUtils.TFile.ReadAllLines 、流等)

<小时/>

代码的部分修复版本可能如下所示(仍然使用老式 Pascal I/O 和低效的数组处理):

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils;

var
x: text;
arr: array of string;

begin

// Load file to string array (old and inefficient way)
AssignFile(x, 'D:\test.txt');
Reset(x);
try
while not Eof(x) do
begin
SetLength(arr, Length(arr) + 1);
Readln(x, arr[High(Arr)]);
end;
finally
CloseFile(x);
end;

Randomize;

// Print strings randomly
while True do
begin
Writeln(Arr[Random(Length(Arr))]);
Readln;
end;

end.

如果你想解决低效的数组问题,但仍然不使用现代类,请分块分配:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils;

var
x: text;
s: string;
arr: array of string;
ActualLength: Integer;


procedure AddLineToArr(const ALine: string);
begin
if Length(arr) = ActualLength then
SetLength(arr, Round(1.5 * Length(arr)) + 1);
arr[ActualLength] := ALine;
Inc(ActualLength);
end;

begin

SetLength(arr, 1024);
ActualLength := 0; // not necessary, since a global variable is always initialized

// Load file to string array (old and inefficient way)
AssignFile(x, 'D:\test.txt');
Reset(x);
try
while not Eof(x) do
begin
Readln(x, s);
AddLineToArr(s);
end;
finally
CloseFile(x);
end;

SetLength(arr, ActualLength);

Randomize;

// Print strings randomly
while True do
begin
Writeln(Arr[Random(Length(Arr))]);
Readln;
end;

end.

但是如果您能够学习现代类(class),事情就会变得容易得多。以下示例使用现代 Delphi RTL:

通用TList<T>自动处理高效扩展:

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils, Generics.Defaults, Generics.Collections;

var
x: text;
s: string;
list: TList<string>;

begin

list := TList<string>.Create;
try

// Load file to string array (old and inefficient way)
AssignFile(x, 'D:\test.txt');
Reset(x);
try
while not Eof(x) do
begin
Readln(x, s);
list.Add(s);
end;
finally
CloseFile(x);
end;

Randomize;

// Print strings randomly
while True do
begin
Writeln(list[Random(list.Count)]);
Readln;
end;

finally
list.Free;
end;

end.

但是你可以简单地使用TStringList :

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils, Classes;

var
list: TStringList;

begin

list := TStringList.Create;
try

list.LoadFromFile('D:\test.txt');

Randomize;

// Print strings randomly
while True do
begin
Writeln(list[Random(list.Count)]);
Readln;
end;

finally
list.Free;
end;

end.

或者您可以保留数组方法并使用 IOUtils.TFile.ReadAllLines :

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils, IOUtils;

var
arr: TArray<string>;

begin

arr := TFile.ReadAllLines('D:\test.txt');

Randomize;

// Print strings randomly
while True do
begin
Writeln(arr[Random(Length(arr))]);
Readln;
end;

end.

正如您所看到的,现代方法更加方便(代码更少)。它们的速度也更快,并为您提供 Unicode 支持。

<小时/>

注意:以上所有代码片段均假设该文件至少包含一行。如果情况并非如此,它们将会失败,并且在实际/生产代码中,您必须验证这一点,例如就像

  if Length(arr) = 0 then
raise Exception.Create('Array is empty.');

  if List.Count = 0 then
raise Exception.Create('List is empty.');

// Print strings randomly之前部分,假设数组/列表不为空。

关于delphi - 在 Pascal 中将文本文件中的字符串读入数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58297496/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com