morodis napisał(a)
Tylko za bardzo, nie wiem jak to wszystko mam napisać w kompilatorze, żeby działało poprawnie. Możecie mnie jakoś naprowadzić?
Naprowadzając - kod pisze się w edytorze, a kompilatora nawet nie widać; Heh, widzę że Ty też padłeś ofiarą systemu nauczania - "otwórzcie kompilatory"... :]
babubabu napisał(a)
Tylko zamiast tych textfilów assignów i innych użyj TStringList.LoadFromFile
[...]
Tu pasowało by uściślić;
Klasa TStringList
jest przede wszystkim wygodna - zawiera kupkę bardzo przydatnych metod i właściwości; Niestety ma jeden minus - nie umożliwia buforowania odczytu, przez co cały plik musi zostać załadowany do pamięci (np. za pomocą metody LoadFromFile
); Przy małych plikach nie ma to znaczenia, natomiast przy dużych i bardzo dużych owszem;
Druga sprawa to konstrukcja z AssignFile, Reset/Rewrite/Append i CloseFile; To nie jest konstrukcja przestarzała czy z jakiegokolwiek innego powodu niezalecana; Po pierwsze umożliwia buforowanie odczytu/zapisu, po drugie umożliwia obsługę błędów I/O, bez korzystania z mechanizmu wyjątków; Konstrukcja ta nie jest tak wygodna jak gotowe klasy kontenerów, jednak ma swoje plusy i warto mieć taką obsługę plików obcykaną;
Wracając do samego programu - nie podałeś @morodis informacji o tym, czy liczba linii w plikach jest ograniczona; W stricte szkolnych programach to jest norma; Zakładam, że nie może ich być więcej niż 50, a także że wspomniane X
jest stałe - tego również nie podałeś; W razie czego zawsze możesz dopytać; Program pisany dla FPC:
const
MAGIC_X = 20;
type
TFileLines = array [0 .. 49] of String;
type
TFileContent = record
Count: Integer;
Lines: TFileLines;
end;
procedure LoadFile(const AFileName: String; out AContent: TFileContent);
var
fInput: TextFile;
begin
AssignFile(fInput, AFileName);
Reset(fInput);
try
AContent.Count := 0;
while not EoF(fInput) do
begin
ReadLn(fInput, AContent.Lines[AContent.Count]);
Inc(AContent.Count);
end;
finally
CloseFile(fInput);
end;
end;
procedure CreateCombinedFile(const AFileName: String; const AContentA, AContentB: TFileContent);
var
fOutput: TextFile;
intX: Integer;
begin
AssignFile(fOutput, AFileName);
ReWrite(fOutput);
try
for intX := 0 to MAGIC_X - 1 do
WriteLn(fOutput, AContentA.Lines[Random(AContentA.Count)], ' ', AContentB.Lines[Random(AContentB.Count)]);
finally
CloseFile(fOutput);
end;
end;
var
fcContentA, fcContentB: TFileContent;
begin
Randomize();
LoadFile('A.txt', fcContentA);
LoadFile('B.txt', fcContentB);
CreateCombinedFile('C.txt', fcContentA, fcContentB);
end.
To taki prosty przykład; Nie wiem czy zapoznali Was ze starymi obiektami (alokowanymi na stosie), w każdym razie można by zrobić z typu TFileContent
właśnie stary obiekt, dodać do niego metodę RandomLine
:
type
TFileContent = object
Count: Integer;
Lines: TFileLines;
function RandomLine(): String;
end;
function TFileContent.RandomLine(): String;
begin
Result := Lines[Random(Count)];
end;
i użyć tej metody w pętli łączącej - wyjdzie nieco krócej i czytelniej:
for intX := 0 to MAGIC_X - 1 do
WriteLn(fOutput, AContentA.RandomLine(), ' ', AContentB.RandomLine());
Ewentualnie zostawię to jako ciekawostkę.