Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Списки

Автор: Rom1k 16.05.2007 18:59

Считать список с файла(.txt) и вывести его на экран.
в файле дано
Фамилию имя отчество 4 оценки и дополнительный балл(если он есть,тогда занести,если его нет,оставить пустым) и подсчитать средний балл.

Пример работы программы:

Цитата

Иванов Иван Иванович 3 4 3 3 3
Петров Петр Петрович 3 4 4 2
Юрьев Юрий Юрьевич 2 2 3 4


Вот что программа должна выводить на экран:
Цитата

ФИО оценка 1 оценка 2 оценка 3 доп. балл средний балл
Иванов Иван Иванович 3 4 3 3 3.2
Петров Петр Петрович 3 4 4 0 3.25
Юрьев Юрий Юрьевич 2 2 3 0 2.75


вот текст программы.Я думаю,что у меня даже с файла считывает неправильно:

program m1;
Uses CRT;
type
PData = ^TData;
TData = record
fam,imya,otch:string; {Фамилия, имя, отчество}
marks:array[1..3] of integer; {3 оценки}
bal:byte; {Дополнительный балл}
SB:real; {Средний балл}
next:PData;
end;
Var
Head,Tail,P:PData;
i:integer;
N:byte;
nn:byte;
{--------------------------------------------------------------------------}
procedure vvod(var Rec:TData;var n:byte);
var
s:real;{Сумма 3 оценок}
p:integer;{Позиция в строке ввода}
error:integer;{код ошибки при преобраз. строки в число}
f:text;
st:string;
bals:string;{Строки,содерж bal}
Smarks:array[1..3] of string;
Begin
Assign (f,'sot.txt');
reset(f);
s:=0;
p:=pos(' ',st); {Р присваивает позицию пробела}
while not eof (f) do {Пока не конец файла,делаем}
begin
readln(f,st);
rec.fam:=copy(st,1,p-1); {Вырезаем фамилию}
delete(st,1,p);
rec.imya:=copy(st,1,p-1); {Вырезаем имя}
delete(st,1,p);
rec.otch:=copy(st,1,p-1); {Вырезаем отчество}
delete(st,1,p);
for i:=1 to 3 do {От 1ой до 3ей оценки}
begin
Smarks[i]:=copy(st,1,p-1); {Вырезаем оценку}
val(Smarks[i],rec.marks[1],error); {Преобразовываем строку в число}
s:=s+rec.marks[i]; {Накапливаем сумму оценок}
delete(st,1,p); {Удаляем i оценку из строки}
end;
bals:=copy(st,1,p-1);
val(bals,rec.bal,error);
if rec.bal = 0 then {Если дополнительного балла нет}
rec.sb:=s/3
else
rec.sb:=s+rec.bal/4;
n:=n+1;
close(f);
end;{while}
end;{vvod}
{--------------------------------------------------------------------------}
procedure add(var nn:byte);
var
p:PData;
begin
Head:=nil;
Tail:=nil;
new(p);
vvod(p^,nn);
for i:=1 to nn do
begin
if Head=nil then head:=p
else tail^.next:=p;
Tail:=p;
p^.next:=nil;
end;{for}
end;{add}
{--------------------------------------------------------------------------}
procedure prosmotr(var nn:byte);
var
p:pdata;
i,v:byte;
begin
WriteLn('Результат: ');
P:=Head;
While P<>nil do
for v:=1 to nn do
begin
Write(n,') ',P^.fam:3,p^.imya:3,p^.otch:3);
for i:=1 to 3 do
write(p^.marks[i]:3);
writeln(p^.bal:3,' ',p^.SB:4:1);
P:=P^.next;
v:=v+1;
end;{while}
end;{prosm}
{--------------------------------------------------------------------------}
Begin{main}
clrscr;
add(n);
prosmotr(n);
readkey;
END.




Автор: volvo 16.05.2007 21:09

Цитата
Я думаю,что у меня даже с файла считывает неправильно:
Парсит строку точно неправильно... Вот так можно поправить твой код, чтобы он нормально работал (это если без переделывания):

    p:=pos(' ',st);
rec.fam:=copy(st,1,p-1);
delete(st,1,p);

p:=pos(' ',st); { позиция пробела должна пересчитываться постоянно, иначе будет бред ... }
rec.imya:=copy(st,1,p-1);
delete(st,1,p);

p:=pos(' ',st);
rec.otch:=copy(st,1,p-1);
delete(st,1,p);
for i:=1 to 4 do { <--- у тебя ж 4 оценки, а не 3 !!! }
begin
p := pos(' ', st);
Smarks[i]:=copy(st,1,p-1);
val(Smarks[i],rec.marks[1],error);
s:=s+rec.marks[i];
delete(st,1,p);
end;
bals:=copy(st,1,p-1);
val(bals,rec.bal,error);
if rec.bal = 0 then
rec.sb:=s/3
else
rec.sb:=s+rec.bal/4;

Но можно и значительно упростить программу, заменив, например,
fam,imya,otch:string;  {Фамилия, имя, отчество}

на
names: array[1 .. 3] of string;

и обработку закинув в цикл...

Автор: Rom1k 16.05.2007 21:23

Что-то с файлом не то.Он его не читает.Что я там мог сделать не правильно?!
Да.Насчёт упрощения-хорошая идея,пожалуй так и сделаю.

Автор: volvo 16.05.2007 21:29

Цитата
Что я там мог сделать не правильно?!
blink.gif А зачем ты Close(f) внутрь цикла While засунул?

Добавлено через 3 мин.
Да и вообще, я не понял чего ты хочешь добиться... Если в Vvod читаются ВСЕ данные сразу из файла, то у тебя ничего не выйдет, потому что rec - то может хранить только данные из одной строки... Все-таки придется тебе пересматривать структуру программы полностью...

Автор: Rom1k 16.05.2007 21:37

Убрал.А всё равно ничего не выводит.Я думаю не правильно считывает.помоги.Плиз.Оч надо blink.gif

Добавлено через 1 мин.

Цитата

Если в Vvod читаются ВСЕ данные сразу из файла, то у тебя ничего не выйдет, потому что rec - то может хранить только данные из одной строки.

а мне надо его по строкам брать и вырезать.Мне объясняла преподаватель,что надо цикл какой-то делать.Только я не пойму. nea.gif


Прикрепленные файлы
Прикрепленный файл  LLL33.PAS ( 3.9 килобайт ) Кол-во скачиваний: 232

Автор: volvo 16.05.2007 22:24

Погоди... У тебя задание на списки, так? Тогда набросок программы должен быть таким:

procedure vvod(var f: text; var Rec: TData);
begin
readln(f, st); { <--- читаешь из файла строку }

{ и парсишь ее, заполняешь структуру Rec }
end;

procedure add(var list: PData; var rec: TData);
begin
{ здесь к списку List добавляется еще она запись - Rec }
end;

procedure prosmotr(var list: PData);
begin
{ здесь - печатаешь список list }
end;

{ ну, и основная программа... }
var
f: text;
r: TData;
root: PData;
begin
root := nil; { <--- это - указатель на начало списка }
assign(f, 'имя файла'); reset(f);
while not eof(f) do begin
vvod(f, r); { <--- читаешь данные из файла в структуру ... }
add(list, r); { <--- и добавляешь структуру в список }
end;

prosmotr(list); { <--- распечатываешь содержимое списка }
end.

Попробуй сделать программу сам...

Автор: Rom1k 16.05.2007 22:44

щас.попробую.спасибо большое.если что не будет получатся,сюда напишу.

Автор: Rom1k 16.05.2007 23:14

Цитата
procedure add(var list: PData; var rec: TData);
begin
{ здесь к списку List добавляется еще она запись - Rec }
end;

что-то вот это я не понимаю blink.gif

Что сдесь list должно делать? или передать ему параметры list:=Rec(p^) или что?!

Автор: volvo 16.05.2007 23:31

Ты же делал нечто подобное... Я, кстати, немного ошибся - надо описывать не только указатель на голову, но и указатель на хвост, и делать так:

procedure add(var list, tail: pdata; var rec: tdata);
var p: PData;
begin
new(p);

if list = nil then list := p
else tail^.next := p;

Tail := p;
p^ := rec;
p^.next := nil;
end; { add }

Автор: Rom1k 17.05.2007 0:11

а это я понял.тут мы заполняем список.я не понимал просто при чём там rec.это типа передает параметры с rec в list и tail для добавления в список?!

Добавлено через 14 мин.
вот я сделал всё,как Вы сказали.в ответе везде выводит ноль.что тут не правильно?
не пойму(((



Прикрепленные файлы
Прикрепленный файл  RRR.PAS ( 3.1 килобайт ) Кол-во скачиваний: 227

Автор: volvo 17.05.2007 1:47

Ну, допустим сделал ты ДАЛЕКО не все, что я сказал... Посмотри:
Прикрепленный файл  1_1.pas ( 2.97 килобайт ) Кол-во скачиваний: 418


И реши, кстати, уже наконец, сколько оценок надо обрабатывать у каждого... В условии пишешь одно, в решении - другое, потом начнется, это не так, то не эдак...

Автор: Rom1k 17.05.2007 1:50

вау...да.3 оценки вводить надо.

Автор: Rom1k 17.05.2007 2:41

Смотрите,когда я ввожу так

Цитата
Петров Петр Петрович 4 5 4 3
Сидоров Василий Васильевич 4 5 4
Юрьев Алексей Юрьевич 4 3 4 2
Иванов Евгений Евгеньевич 5 4 3 2
Питеркин Вячеслав Михайлович 3 3 2


Он мне выводит :
Изображение
Туда он не заносит почему-то оценки.пробовал исправить,всё-равно тоже самое.ЧТо там не так?

Автор: volvo 17.05.2007 3:03

Ты ориентируешься по пробелам, когда читаешь числа из строки, а когда в строке осталось одно число (доп. балла нет), то P становится равным 0, и последняя оценки не читается из строки... Исправляется очень просто:

{ в процедуре Vvod }
...
readln(f,st);
st := st + ' '; { добавляешь к прочитанной из файла строке пробел }
...

Автор: Rom1k 17.05.2007 3:22

ааа...точно.а я сразу не догадался,спасибо большое!!!

Автор: Rom1k 17.05.2007 4:22

аааа....мне ещё дали дополнительное условие.сформировать новый список из тех,чей средний балл больше,либо равен 4.5.

Это т.е надо просто написать


var
tail2,head2:Pdata;
r:TData;
...

if p^.bal >= 4.5 then
add(head2,tail2,r2);


или это делается как-то по-другому?!

Автор: volvo 17.05.2007 4:27

Да, именно так...

Автор: Rom1k 17.05.2007 4:57

вроде бы всё правильно,но опять он ничего не выводит.снизу прога.потом файл,НА КОТОРОМ ТЕСТИЛ...что там не правильно?(


Прикрепленные файлы
Прикрепленный файл  1_1.PAS ( 3.16 килобайт ) Кол-во скачиваний: 229
Прикрепленный файл  SOT.TXT ( 166 байт ) Кол-во скачиваний: 229

Автор: volvo 17.05.2007 5:06

var head2, tail2, p: pdata;

...
head2 := nil;
p := head;
while p <> nil do begin
if p^.sb >= 4.5 then add(head2, tail2, p^);
p := p^.next;
end;
prosmotr(head2);
...

Автор: Rom1k 17.05.2007 12:19

volvo спасибо Вам большое.Вы не представляете,как Вы меня выручили good.gif

Автор: Rom1k 17.05.2007 22:46

оказывается мне ещё надо это все разместить в типизированном файле.т.е надо его создать и внести туда head2,tail2 ) т.е строки в новом файле должны выглядеть так:

Цитата

Сидоров Василий Васильевич 5 5 4 4.7
Юрьев Алексей Юрьевич 4 5 5 4 4.5

получается надо создать файл и разместить всё это в нём.Это делается так?

begin
...
....
head2:=nil;
assign(n,'sot2.txt');
rewrite(n)
while p<>nil do begin
write(n,{???});
p:=p^.next;
end{while}
close(n);
end.


Добавлено через 11 мин.
и всё-таки я думаю,что я как всегда намудрил в программе. blink.gif вот программа:
Прикрепленный файл  1_1.PAS ( 3.77 килобайт ) Кол-во скачиваний: 409

Вот то,на чём тестил:
Прикрепленный файл  SOT.TXT ( 162 байт ) Кол-во скачиваний: 400

заранее благодарен за помощь!

Автор: volvo 17.05.2007 23:09

begin  
...
assign(n,'sot2.dat'); { <--- Файл типизированный, не вводи пользователя в заблуждение }
rewrite(n)

p := head2;
while p<>nil do begin
write(n, p^); { <--- Правда поле next после записи будет содержать мусор, но ... }
{
надо сразу давать полное задание - видишь, к чему приводят "костыли"?
теперь чтобы от этого избавиться надо переписывать программу!
}
p:=p^.next;
end{while}
close(n);
end.


Автор: Rom1k 17.05.2007 23:20

ну,так получилось.Мне просто преподаватель условие добавила.Я не виноват(
А много там надо переписывать??? Мне просто надо,чтобы все работало(

Цитата

while p<>nil do begin
write(n, p^); {<---Здесь у меня выдаёт ошибку 64:Cannot Read or Write variables of this type.}

Автор: volvo 17.05.2007 23:24

Я что, тепепат, знать как именно ты описываешь файл N ?

Автор: Rom1k 17.05.2007 23:35

а как его надо описать?
n:text ?
много там надо переписывать в моей пограмме???


Автор: Rom1k 18.05.2007 0:33

погмогите пожалуйста(

Автор: volvo 18.05.2007 0:43

Я уже говорил тебе, что ты в задании делаешь одно, а в условии у тебя - совсем другое? Опять то же самое:

Цитата(Rom1k @ 17.05.2007 18:46)
оказывается мне ещё надо это все разместить в типизированном файле.


Цитата(Rom1k @ 17.05.2007 19:35)
а как его надо описать?
n:text ?

Вот когда ты решишь для себя, типизированный файл тебе нужен, или все-таки текстовый, тогда приходи...

Автор: Rom1k 18.05.2007 0:45

ну,да.мне нужно в типизированном файле.Тогда как его объявить?

Автор: volvo 18.05.2007 0:53

Тогда объяви

var n: file of TData;

и будет тебе счастье... Только чтобы просмотреть его тебе понадобится написать еще одну программу, я так понимаю, это будет следующий костыль, который тебя заставит делать преподаватель... Так что будь готов smile.gif

Автор: Rom1k 18.05.2007 1:00

volvo если Вам не тяжело, вы можете посмотреть мою программу.
Вообще в файл типизированный не понятно что записывает,что делать?

Добавлено через 4 мин.
Вот программа: Прикрепленный файл  1_1.PAS ( 3.93 килобайт ) Кол-во скачиваний: 405


Добавлено через 4 мин.
надо,чтобы нормально в файле всё выводилось...подскажите пожалуйста,что надо делать?

Добавлено через 18 мин.

Цитата(volvo @ 17.05.2007 21:53) *

Тогда объяви
var n: file of TData;

и будет тебе счастье... Только чтобы просмотреть его тебе понадобится написать еще одну программу, я так понимаю, это будет следующий костыль, который тебя заставит делать преподаватель... Так что будь готов smile.gif

а что мне теперь надо написать?конкретно? и там много?

Автор: volvo 18.05.2007 1:38

Цитата
Вообще в файл типизированный не понятно что записывает,что делать?
Ну я же тебе говорил, что просмотреть типизированный файл в блокноте тебе не удастся. Что ты написал, тебе процитировать? Теперь опять начинается старая песня - надо ЕЩЕ и ЕЩЕ?

Автор: Rom1k 18.05.2007 1:41

нет,мне просто надо исправить,чтобы в типизированный файл нормально выводилось,иначе мне туго придется.Вы можете объяснить как мне надо исправить или помочь исправит?! wacko.gif .

Автор: volvo 18.05.2007 1:54

Нельзя сделать так, чтобы выводилось "нормально", потому что в типизированный файл пишется машинное представление данных, понимаешь? Машинное... А ты не машина, а человек, поэтому ты читаешь текстовые файлы, а не типизированные...

Кстати, в файл все прекрасно заносится, хочешь убедиться? Запусти программу... Она напечатает тебе кроме всего прочего еще и то, что сохранилось в файле...


Прикрепленные файлы
Прикрепленный файл  1_1.pas ( 3.6 килобайт ) Кол-во скачиваний: 193

Автор: Rom1k 18.05.2007 2:06

так.значит,смотрите.с меня не будут требовать тогда нормального отображения sot2.dat ? если в задании дано,что файл типизированный?!
Да,и что такое {$mode tp} ???
У меня пишет: Error 17: Invalid compiler directive.

Автор: volvo 18.05.2007 2:30

Ну, правильно, убери эту строку, я же компилирую под FPC, но с имитацией Турбо Паскаля... Просто забыл удалить...