![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Здраствуйте. Нужна помощь
Вот условие задачи: "Из двух типизированных файлов с компонентами записей type Stud = record Year: Integer; Name: String[20]; end; получить текстовый файл, в котором объединены эти два файла, но повторяющихся записей быть не должно. в каждом из файлов по отдельности повторяющихся записей нет. а если вместе то могут быть. отсортировать результирующий файл по убыванию года. вывести на экран исходные файлы, результирующий файл." пример: 1 файл Alexander 1989 Masha 1983 2 файл Misha 1932 Gera 1902 Masha 1983 результирующий файл: Alexander 1989 Masha 1983 Misha 1932 Gera 1902 Бьюсь над этой прогой уже довольно долго, получаю всевозможные ошибки. Через минут 5 выложу свой код, но он не правильно работает(поясню почему). Пожалуйста если есть возможность напишите эту программу, по примеру я всё пойму. (через 5 минут своё выложу) |
|
#2
|
||||
|
||||
|
Код:
var
f: file of Stud;
i, j, n, k: integer;
a1, a2: array of Stud;
t: Stud;
begin
AssignFile(f, 'C:\file1.dat');
Reset(f);
i := 0;
while not eof(f) do
begin
SetLength(a1, i + 1);
Read(f, a1[i]);
inc(i);
end;
CloseFile(f);
AssignFile(f, 'C:\file2.dat');
Reset(f);
n := 0;
while not eof(f) do
begin
SetLength(a2, n + 1);
Read(f, a2[n]);
inc(n);
end;
CloseFile(f);
j := i;
dec(n);
while n >= 0 do
begin
k := i - 1;
while k >= 0 do
begin
if (a1[k].Name = a2[n].Name) and (a1[k].Year = a2[n].Year) then
break;
dec(k);
end;
if k = -1 then
begin
SetLength(a1, j + 1);
a1[j].Year := a2[n].Year;
a1[j].Name := a2[n].Name;
inc(j);
end;
dec(n);
end;
// Sorting
for i := 0 to j - 2 do
begin
for n := i + 1 to j - 1 do
if (a1[i].Year > a1[n].Year) then
begin
t.Year := a1[i].Year;
t.Name := a1[i].Name;
a1[i].Year := a1[n].Year;
a1[i].Name := a1[n].Name;
a1[n].Year := t.Year;
a1[n].Name := t.Name;
end;
end;
AssignFile(f, 'C:\file.dat');
Rewrite(f);
for i := 0 to j - 1 do
begin
Write(f, a1[i]);
Writeln(a1[i].Year, ' ', a1[i].Name);
end;
CloseFile(f);
Writeln('Ready');
Readln;
end. |
|
#3
|
|||
|
|||
|
файл 1
alexander1992 masha1992 или alexander 1992 masha 1992 пробовал итак и так файл 2 alexander1992 petr1982 bora1711 и с пробелами пробовал. результат на экране : 1919902218 lexander1992 petr19 Ready результат в файле (*)lexander1992 petr19 bor (заместо * там стоит странный значёк) Явно видно, что программа работает не верно. обрезаются имена, выводятся странные цифры и значки. |
|
#4
|
||||
|
||||
|
Цитата:
Ну дык ты же щас приводишь просто список имен и годов, это не типизированный. ![]() Последний раз редактировалось BoRoV, 13.12.2010 в 20:46. |
|
#5
|
|||
|
|||
|
типизированный, это когда все переменные байтовые ?
что-то я не очень понял как он задаётся. в самом компиляторе создаётся? (у нас этой темы не было на лекциях, поэтому я так фейлю, пытаюсь гуглить, но там только про байты говорят, а примера нет) |
|
#6
|
||||
|
||||
|
Цитата:
Код:
var f: file of Stud; |
|
#7
|
|||
|
|||
|
я не могу понять, я ошибаюсь, когда данные задаю в dat файлах или где-то в коде надо что-то поменять?
я лично думаю, что в дат файле ошибаюсь... |
|
#8
|
||||
|
||||
|
Ты обещал свой код показать. На нём и будем править ошибки.
Вот так записываем первый и второй файл. Код:
var
f: file of Stud;
res: char;
t: Stud;
begin
AssignFile(f, 'C:\file1.dat');
Reset(f);
Seek(f, filesize(f));
repeat
Write('Year : ');
Readln(t.Year);
Write('Name : ');
Readln(t.Name);
Write(f, t);
Write('Next (y/n): ');
readln(res);
until (res = 'n');
CloseFile(f);
Writeln('Ready');
Readln;
end.Последний раз редактировалось BoRoV, 13.12.2010 в 22:02. |
|
#9
|
|||
|
|||
|
извините за задержу, вот мой код(нерабочий)
основные проблемы: 1. при считывании из файла, последняя строка обрезается до1 буквы, а после идут крякозабры и иероглифы. 2. два файла не считывает, а считывает лишь один. сижу над прогой несколько дней, и теперь она помоему ещё хуже стала работать.(в начале считывался из двух только 1 файл в конце с крякозабрами, а теперь вобще ничего не считывает) Код:
program example;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
Stud = record
Name: String[20];
Year: Integer;
end;
StFile = file of Stud;
procedure OutputFile(var FileToWrite: StFile);
var
TempRecord: Stud;
begin
Reset(FileToWrite);
while not EOF(FileToWrite) do
begin
Read(FileToWrite, TempRecord);
with TempRecord do
Write(Name);
Writeln;
end;
end;
procedure SortFile(var FileToSort: StFile);
var
I, J: Integer;
MaximumYear: Integer;
TempRecord: stud;
IndexOfMaxRecord: Integer;
RecordNumberI: stud;
MinRecord: stud;
begin
for I := 0 to FileSize(FileToSort) - 2 do
begin
Seek(FileToSort, I);
Read(FileToSort, RecordNumberI);
MaximumYear := RecordNumberI.Year;
IndexOfMaxRecord := I;
for J := I + 1 to FileSize(FileToSort) - 1 do
begin
Read(FileToSort, TempRecord);
if TempRecord.Year > MaximumYear then
begin
MaximumYear := TempRecord.Year;
IndexOfMaxRecord := J;
end;
end;
Seek(FileToSort, IndexOfMaxRecord);
Read(FileToSort, MinRecord);
Seek(FileToSort, IndexOfMaxRecord);
Write(FileToSort, RecordNumberI);
Seek(FileToSort, I);
Write(FileToSort, MinRecord);
end;
end;
procedure Input(var F, G: Stfile; out J: TextFile);
var
Temp: Stud;
begin
Reset(F);
Rewrite(J);
Reset(J);
while not Eof(F) do
begin
Read(F, Temp);
Write(J, Temp.Name);
end;
Reset(G);
while not Eof(G) do
begin
Read(G, Temp);
Write(J, Temp.Name);
end;
end;
var
F: StFile;
A: StFile;
J: Textfile;
begin
Assign(F, 'C:\file1.dat');
Reset(F);
Assign(A, 'C:\file1.dat');
Reset(A);
Writeln('Исходный файл:');
OutputFile(F);
Writeln;
Writeln('Исходный файл №2:');
OutputFile(A);
Writeln;
Assign(J, 'result.txt');
Rewrite(J);
Input(F, A, J);
SortFile(F);
Writeln;
Writeln('Отсортированный исходный файл:');
OutputFile(F);
CloseFile(F);
CloseFile(A);
Readln;
end.Последний раз редактировалось Yreng, 13.12.2010 в 21:34. |
|
#10
|
||||
|
||||
|
Ну код наверное не твой
а где-то взят на просторах интернета. Я привёл уже и код как записывать в файлы, бери и пользуйся. И у меня кажется проще чем в том "твоём" коде. |
|
#11
|
|||
|
|||
|
Кроме сортировки всё полностью моё, а сортировка на половину моя(переделана из сортировки массива с помощью процедуры, я ей не занимался особо, т.к. до этого баги были).
а если файлы были бы не типизированными, а текстовыми, то что это изменило было? файлы бы задавались через текстовый редактор, а не программно? тогда как раз бы и были такие глюки, как я описал(урезанная строка с иероглифами к примеру). большое спасибо за помощь! |
|
#12
|
|||
|
|||
|
какую-то фигню ты написал.
у меня получилось что-то вот такое (это если по простому): Код:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TStud = record
Name : String[20];
Year : Integer;
end;
var
A : Array Of TStud;
A1, A2 : Array Of TStud;
procedure ReadFile1(AFileName : String);
var
F : File Of TStud;
begin
SetLength(A1,0);
If FileExists(AFileName) Then
Begin
AssignFile(F,AFileName);
Reset(F);
While Not EOF(F) Do
Begin
SetLength(A1,Length(A1)+1);
Read(F,a1[High(A1)]);
End;
CloseFile(F);
End;
end;
procedure ReadFile2(AFileName : String);
var
F : File Of TStud;
begin
SetLength(A2,0);
If FileExists(AFileName) Then
Begin
AssignFile(F,AFileName);
Reset(F);
While Not EOF(F) Do
Begin
SetLength(A2,Length(A2)+1);
Read(F,A2[High(A1)]);
End;
CloseFile(F);
End;
end;
procedure TypeArray(AA : Array Of TStud);
var
I : Integer;
begin
For I := Low(AA) To High(AA) Do
WriteLn(AA[i].Year,' ',AA[i].Name);
end;
procedure Swap(AA : Array Of TStud; I, J : Integer);
var
T : TStud;
begin
T := AA[i];
AA[i] := AA[J];
AA[J] := T;
end;
procedure SortArray(AA : Array Of TStud);
var
I, J : Integer;
begin
For I := Low(AA) To High(AA)-1 Do
For J := I+1 To High(AA) Do
If AA[i].Year = AA[J].Year
Then
Begin
If AA[i].Name > AA[J].Name Then Swap(AA,I,J);
End
Else
If AA[i].Year > AA[J].Year Then Swap(AA,I,J);
end;
function IsExists(T : TStud; AA : Array Of TStud) : Boolean;
var
I : Integer;
begin
Result := False;
For I := Low(AA) To High(AA) Do
If (AA[i].Year = T.Year) And (AA[i].Name = T.Name) Then
Begin
Result := True;
Break;
End;
end;
procedure ComposeIntoResult(AA : Array Of TStud);
var
I : Integer;
begin
For I := Low(AA) To High(AA) Do
If Not IsExists(AA[i],A) Then
Begin
SetLength(A,Length(A)+1);
A[High(A)] := AA[i];
End;
end;
procedure WriteFile(AFileName : String; AA : Array Of TStud);
var
I : Integer;
F : File Of TStud;
begin
AssignFile(F,AFileName);
Rewrite(F);
For I := Low(AA) To High(AA) Do
Write(F,AA[i]);
CloseFile(F)
end;
begin
ReadFile1('In1.dat');
ReadFile2('In2.dat');
WriteLn('--- File 1 ---');
TypeArray(A1);
WriteLn;
WriteLn('--- File 2 ---');
TypeArray(A2);
WriteLn;
SetLength(A,0);
ComposeIntoResult(A1);
ComposeIntoResult(A2);
SortArray(A);
WriteLn('--- Result ---');
TypeArray(A);
WriteLn;
Write('Press Enter to close...');
ReadLn;
end. |
|
#13
|
||||
|
||||
|
Ну это тоже не совсем красиво
![]() Код:
procedure ReadFile1(AFileName : String);
var
F : File Of TStud;
begin
SetLength(A1,0);
If FileExists(AFileName) Then
Begin
AssignFile(F,AFileName);
Reset(F);
While Not EOF(F) Do
Begin
SetLength(A1,Length(A1)+1);
Read(F,a1[High(A1)]);
End;
CloseFile(F);
End;
end;
procedure ReadFile2(AFileName : String);
var
F : File Of TStud;
begin
SetLength(A2,0);
If FileExists(AFileName) Then
Begin
AssignFile(F,AFileName);
Reset(F);
While Not EOF(F) Do
Begin
SetLength(A2,Length(A2)+1);
Read(F,A2[High(A1)]);
End;
CloseFile(F);
End;
end;Лучше это всё через одну ф-ию реализовать ![]() Код:
procedure _ReadFile(AFileName : String; var A: Array of TStud);
var
F : File Of TStud;
begin
SetLength(A,0);
If FileExists(AFileName) Then
Begin
AssignFile(F,AFileName);
Reset(F);
While Not EOF(F) Do
Begin
SetLength(A,Length(A)+1);
Read(F,A[High(A)]);
End;
CloseFile(F);
End;
end; |
|
#14
|
||||
|
||||
|
Вообще-то условием задачи не запрещено использовать класс TStringList
![]() Остается взять только читалку типизированной структуры и загнать в класс. Все стальное там уже реализовано. |
|
#15
|
|||
|
|||
|
теперь я понял свою ошибку(я файл в ворд паде создавал, а надо было через программу). потренировался, всё ок.
только одна проблема. я взял вашу программу и дополнил её вводом этих файлов (file1.dat и file2.dat), на экране всё работает правильно, а когда открываю file.dat , то там неразбериха, странные символы и т.д. Это как-то можно испрвить или это из-за того, что файл не txt, поэтому в него так записывается? Код:
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
Stud = record
Year: Integer;
Name: String[20];
end;
var
f: file of Stud;
i, j, n, k: integer;
a1, a2: array of Stud;
t: Stud;
res: char;
begin
AssignFile(f, 'C:\file1.dat');
Reset(F);
repeat
Write('Name: ');
ReadLn(t.Name);
Write('Year: ');
ReadLn(t.Year);
Write('res: ');
Write(F, T);
ReadLn(Res);
until (res = 'n');
Closefile(F);
AssignFile(f, 'C:\file2.dat');
Reset(F);
repeat
Write('Name: ');
ReadLn(t.Name);
Write('Year: ');
ReadLn(t.Year);
Write('res: ');
Write(F, T);
ReadLn(Res);
until (res = 'n');
CloseFile(F);
AssignFile(f, 'C:\file1.dat');
Reset(f);
i := 0;
while not eof(f) do
begin
SetLength(a1, i + 1);
Read(f, a1[i]);
inc(i);
end;
CloseFile(f);
AssignFile(f, 'C:\file2.dat');
Reset(f);
n := 0;
while not eof(f) do
begin
SetLength(a2, n + 1);
Read(f, a2[n]);
inc(n);
end;
CloseFile(f);
j := i;
dec(n);
while n >= 0 do
begin
k := i - 1;
while k >= 0 do
begin
if (a1[k].Name = a2[n].Name) and (a1[k].Year = a2[n].Year) then
break;
dec(k);
end;
if k = -1 then
begin
SetLength(a1, j + 1);
a1[j].Year := a2[n].Year;
a1[j].Name := a2[n].Name;
inc(j);
end;
dec(n);
end;
// Sorting
for i := 0 to j - 2 do
begin
for n := i + 1 to j - 1 do
if (a1[i].Year > a1[n].Year) then
begin
t.Year := a1[i].Year;
t.Name := a1[i].Name;
a1[i].Year := a1[n].Year;
a1[i].Name := a1[n].Name;
a1[n].Year := t.Year;
a1[n].Name := t.Name;
end;
end;
AssignFile(f, 'C:\file.dat');
Rewrite(f);
for i := 0 to j - 1 do
begin
Write(f, a1[i]);
Writeln(a1[i].Year, ' ', a1[i].Name);
end;
CloseFile(f);
Writeln('Ready');
Readln;
end. |