Вопросс. Pascal.

Ответить
Mental
Сообщения: 5
Зарегистрирован: 01 янв 2008, 20:48

Задание было такое:
Дан файл F, содержащий сведения о книгах, свединия о каждой из них- это автор, название, год. Найти название книги данного автора.

Я вот написал програмку, пишет в файл данные через пробелы. Каждую запись пишет на новой строчке. Проблемма в том, что не знаю как найти нужный год в файле. Я написа типа if mas.year='2002' then writeln('Naiden',avtor). Но сказали чтоб из файла считывал а не с клавиатуры.=)

Вот подкорректируйте, ток без процедур желательно.

program pr1;
const
izdanie_2000=2000;
type
tablica=record
avtor:string[15];
nazvanie:string[10];
year:longint;
end;
var
x:longint;
n,i:integer;
f:text;
mas:array[1..30] of tablica;
begin
{$I-}
Assign(f,'C:\f.txt');
rewrite(f);
{$I+}
If Ioresult<>0 then
writeln('No File F') else
writeln('n= ');
readln(n);
for I:=1 to n do
with mas do
begin
write('Avtor- ');
readln(avtor);
write(f,avtor,' ');
write('nazvanie - ');
readln(nazvanie);
write(f,nazvanie,' ');
write('God- ');
readln(year);
writeln(f,year,' ');
end; {А хз как дальше -)}
reset(f);
repeat
for i:=1 to 4 do
If not seekEof(f) then
begin
read(f,x);
if x=2002 then
writeln('Naiden');
end;
until seekEof(f);
close(f);
end.

Народ, я не нуб я проболел тему=) Заранее спасибо за помощь.
MOTOCoder
Сообщения: 548
Зарегистрирован: 14 янв 2008, 20:27
Откуда: Россия, Псков

Примерно так:
[syntax='delphi']
var
F:text;
s,y:string; {добавить в var}
year:integer; {добавить в var}
c:integer; {добавить в var}

begin
{Это вставить после "хз как дальше", убрав все с конца }
reset(F);
while not Eof(F) do
begin
readln(F,s);
y:=copy(s,pos('God- ',s)+5,4);
val(y,year,c);
if year=2002 then
writeln('Naiden '+copy(s,pos('Avtor- ',s)+7,length(s)-pos('God- ',s)));
end;
Close(F);
readln;
end.
[/syntax]
Ни что так не ограничивает фантазию программиста, как компилятор...
Serge_Bliznykov
Сообщения: 375
Зарегистрирован: 31 авг 2007, 03:06

Ещё добавлю к решению MOTOCoder.
Дело в том, что Вы с самого начала неправильно опеределили для себя, что файл у вас ТЕКСТОВЫЙ. Подобные задачи просто идеально подходят под работу с ТИПИЗИРОВАННЫМИ файлами. Тем более, что Вы знаете, что такое тип "record" и у Вас уже есть опреедение record для Вашей задачи. (хотя, я бы вместо tablica использовал имя, например OneBook или BookRecord. но это Ваше дело, как называть типы и переменные ;-))
А потом, вместо f:Text пишется:
f : file of tablica;
Записать в файл запись об одной книге - Write(f,mas)
прочитать одну запись - Read(f,mas) Разумеется, вместо mas может быть просто любая переменная типа tablica (var CurrentBook : tablica):
а потом цикл перебирающий все записи в файле и проверяющий их на совпадение с условием:

Код: Выделить всё

while Not eof(f) do begin
  Read(f, CurrentBook);
  if CurrentBook.Year = 2002 then  
    writeln('Книга: Автор: ',CurrentBook.Avtor,' ',
               CurrentBook.nazvanie,' ',CurrentBook.Year:1);
end;
Mental
Сообщения: 5
Зарегистрирован: 01 янв 2008, 20:48

Спс программа работает, есть пару вопросов, тк когда не понимаешь подобную задачу сам не напишешь:

y:=copy(s,pos('God- ',s)+5,4); - что даёт в данном случае "+5,4"?
И ещё
val(y,year,c); Про процедуру Val есле можно тоже разъясните.
MOTOCoder
Сообщения: 548
Зарегистрирован: 14 янв 2008, 20:27
Откуда: Россия, Псков

Функция copy имеет 3 параметра:
1-Исходная строка
2-Начало копируемого блока
3-Длина копируемого блока

pos('God- ',s) определяет позицию подстроки 'God- '.
Далее, прибавив к полученному значению 5(длину подстроки 'God- ' получим
позицию начала номера года(2002).
Последний параметр(4) указывает, что нужно скопировать 4 символа от начальной позиции(если считать, что в номере года 4 символа).

Процепдура Val преобразует строку с числом(y) в значение integer и присваивает это значение переменной year.
В последний параметр (c) записывается номер символа, который недопустим в записи числа, если таковой имеется в строке или 0 если все прошло без ошибок.

P.S. Мне кажется, что Serge_Bliznykov прав, и это типичная задача на типизированные файлы и записи.
Ни что так не ограничивает фантазию программиста, как компилятор...
Mental
Сообщения: 5
Зарегистрирован: 01 янв 2008, 20:48

MOTOCoder спасибо тебе большое.

Процепдура Val преобразует строку с числом(y) в значение integer и присваивает это значение переменной year.

А если y-стринговская переменная? У мня анологичная вторая задача только там надо уже искать фамилию в файле и вывести телефон.

y:=copy(s,pos('Familia- ',s)+5,6); {В году мы знаем сколько символов, а как быть с фамилией?)}
val(y,fam,c); - что в данном случае надо вместо val?
if fam='petrov' then ....
MOTOCoder
Сообщения: 548
Зарегистрирован: 14 янв 2008, 20:27
Откуда: Россия, Псков

Mental, вы записи и типизированные файлы проходили?
Если проходили, то надо использовать их, иначе решение посчитают неверным.
Ни что так не ограничивает фантазию программиста, как компилятор...
Serge_Bliznykov
Сообщения: 375
Зарегистрирован: 31 авг 2007, 03:06

Mental, полностью согласен с мнением MOTOCoder. можете отработать впустую... (если препод скажет, что нужно было использовать типизированные файлы)!! ;-(

конкретно, про Ваш вопрос.
VAL для фамилии (как и для любых текстов) не нужна ;-))
а брать из строки
&quot писал(а):y:=copy(s,pos('Familia- ',s)+5,6);
1) не плюс 5 а плюс 9 (или лучше даже так +length('Familia- ')
а сколько символов брать, так это
надо смотреть, что у вас идёт после фамилии - если Familia-... последняя в строке, берите до конца строки! Если нет - ищите позицию следующего элемента и берите до него.

и ПЕРЕХОДИТЕ НА РАБОТУ С ТИПИЗИРОВАННЫМИ ФАЙЛАМИ!!!
Ответить