Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.11.2013, 01:06   #1
orandzheviyman
Пользователь
 
Регистрация: 11.11.2013
Сообщений: 74
По умолчанию Работа с записями и файлом

Что неправильно? Сейчас компилятор выдаёт ошибку "Строка 23 столбец 16 Переменная не является именем массива"
Код:
CONST MAXbook=100; {максимум книг}
TYPE Tbook=record {данные книги}
     surname:string [20]; {фамилия автора}
     bookname: string [50]; {название книги}
     year:longint; {год выпуска}
     genre:string [30]; {жанр}
       end;

VAR ALLbooks:array [1..MAXbook] of Tbook;
    f:file of Tbook;
    fname:string [20];
    N:integer;{факт число книг}
    M:integer;{для меню}
    i:integer;
    count:char;{для ввода}
    godpoiska:longint;
    
PROCEDURE Poisk (ALLbooks, Q:longint);
 Begin
  assign (f, fname);
  reset (f);
   for i:=1 to N do
    if ALLbooks[i].year=Q then
     writeln ('книги. выпущенные в этом году: ');
     writeln (ALLbooks[i].surname, ALLbooks[i].bookname);
 end;

    
BEGIN
 writeln (' программа учёта книг ');
 writeln ('1 - новый файл');
 writeln ('2 - открыть файл');
 writeln ('3 - выход');
 M:=1;
 while M<>3 do
  begin
   write ('введите имя файла '); readln (m);
  case M of
   1:{пункт 1}
   begin
    write ('введите имя файла: '); readln (fname);
    assign (f, fname);
    rewrite (f);
    i:=1; count:='y';
     while count='y' do
      begin
       writeln ('введите данные ', i, 'ой книги');
       writeln;
       writeln ('фамилия автора: '); read (ALLbooks[i].surname);
       writeln (название книги: '); read (ALLbooks[i].bookname);
       writeln ('год выпуска:    '); read (ALLbooks[i].year);
       writeln ('жанр:           '); read (ALLbooks[i].genre);
        write (f, ALLbooks[i].surname:20,ALLbooks[i].bookname:50,ALLbooks[i].year:4,ALLbooks[i].genre:30);
         i:=i+1;
         write ('продолжить ввод? (y - да,любая кнопка - нет)'); readln (count);
      end;
    close (f);
    N:=i-1;
   end;
  end; 
   2: {пункт 2}
   begin
    write ('введите имя файла: ');
    readln (fname);
    assign (f, fname);
    reset (f);
     for i:=1 to N do begin
      write (ALLbooks.surname:10[i],ALLbooks.bookname:10[i],ALLbooks.year:4[i],ALLbooks.genre:10[i]);
     end;
    writeln ('введите год для поиска: '); read (Q);
    Poisk (f, Q);
   end;
  END.
Помогите, пожалуйста

Последний раз редактировалось orandzheviyman; 27.11.2013 в 01:19.
orandzheviyman вне форума Ответить с цитированием
Старый 27.11.2013, 01:29   #2
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

В процедуре Poisk локальная переменная ALLbooks имеет тип longint, а никакой не массив. Она - просто " тезка " глобальной ALLbooks

И еще - кавычку забыли в
Код:
 writeln ('название книги: ');

Последний раз редактировалось type_Oleg; 27.11.2013 в 01:34.
type_Oleg вне форума Ответить с цитированием
Старый 27.11.2013, 01:35   #3
orandzheviyman
Пользователь
 
Регистрация: 11.11.2013
Сообщений: 74
По умолчанию

Цитата:
Сообщение от type_Oleg Посмотреть сообщение
В процедуре Poisk локальная переменная ALLbooks имеет тип longint, а никакой не массив. Она - просто " тезка " глобальной ALLbooks

И еще - кавычку забыли в
Код:
 writeln ('название книги: ');
Ну я так понимаю в процедуре вообще можно в моём случае написать так:
PROCEDURE Poisk (Q:longint);
или как? Я что-то совсем не оч с этими процедурами и функциями(
orandzheviyman вне форума Ответить с цитированием
Старый 27.11.2013, 08:03   #4
ZX Spectrum-128
Участник клуба
 
Регистрация: 05.11.2013
Сообщений: 1,601
По умолчанию

Да, можно. Все равно с глобальной переменной работаете.
ZX Spectrum-128 вне форума Ответить с цитированием
Старый 27.11.2013, 09:51   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Код:
Ну я так понимаю в процедуре вообще можно в моём случае написать так:
PROCEDURE Poisk (Q:longint);
да. так можно.
Но я бы рекомендовал, если есть возможность ИЗБАВЛЯТЬСЯ в коде от использования ГЛОБАЛЬНЫХ переменных.

в вашем случае код может выглядеть так (я позволил себе ещё кое-что изменить в вашем коде так, как посчитал нужным ):
Код:
const MAXbook = 100; {максимум книг}
type
  Tbook = record {данные книги}
    surname: string[20]; {фамилия автора}
    bookname: string[50]; {название книги}
    year: longint; {год выпуска}
    genre: string[30]; {жанр}
  end;
  TBookArray = array[1..MAXbook] of Tbook;


procedure ShowList(const AB: TBookArray; const N: integer);
var
  i: integer;
begin
  WriteLn; WriteLn('Список книг:');
  for i := 1 to N do
    writeln(AB[i].surname: 15,' ', AB[i].bookname: 15,' ',
      AB[i].year: 4,' ', AB[i].genre: 15);
  writeln;
  WriteLn('Нажмите ENTER для продолжения');
  Readln;
end;


procedure CreateNewFile(var AB: TBookArray; var N: integer; var fName: string);
var
  f: file of Tbook;
  i: integer;
  count: char; {для ввода}
begin
  write('введите имя файла: ');
  readln(fname);
  assign(f, fname);
  rewrite(f);
  i := 1; count := 'y';
  while count = 'y' do
  begin
    writeln('введите данные ', i, 'ой книги');
    writeln;
    write('фамилия автора: '); readLn(AB[i].surname);
    write('название книги: '); readLn(AB[i].bookname);
    write('год выпуска:    '); readLn(AB[i].year);
    write('жанр:           '); readLn(AB[i].genre);
    write(f, AB[i]);
    i := i + 1;
    if i <= MAXbook then begin
      write('продолжить ввод? (y - да,любая кнопка - нет)'); readln(count);
    end
    else count := 'n';
  end;
  close(f);
  N := i - 1;
end;

procedure OpenReadFile(var AB: TBookArray; var N: integer; var fName: string);
var
  f: file of Tbook;
  i: integer;
  count: char; {для ввода}
begin
  count := 'n';
  if (fname <> '') then begin
    write('Использовать имя файла ' + fname + '? (y - да,любой другой символ - нет)');
    readln(count);
  end;

  if (count <> 'y') or (fname <> '') then begin
    write('введите имя файла: ');
    readln(fname);
  end;

  assign(f, fname);
  reset(f);
  N := FileSize(f);
  for i := 1 to N do Read(f, AB[i]);

  writeln;
  WriteLn('Успешно прочитано ', N, ' записей в память.');
  writeln;
  WriteLn('Нажмите ENTER для продолжения');
  Readln;
end;


procedure Poisk(const AB: TBookArray; const N: integer; const FindYear: longint);
var i: integer;
begin
  writeLn;
  writeln('книги. выпущенные в ',FindYear,' году: ');
   for i := 1 to N do
    if AB[i].year = FindYear then
         writeln(AB[i].surname, AB[i].bookname);
  writeln;
  WriteLn('Нажмите ENTER для продолжения');
  Readln;
end;




var ALLbooks: TBookArray;
  fname: string; {имя файла}
  N: integer; {факт число книг}
  M: integer; {для меню}
  godpoiska: longint;


begin
  N := 0;
  M := 0;
  while M <> 9 do begin
    writeln(' программа учёта книг ');
    writeln('1 - создать новый файл');
    writeln('2 - открыть файл и прочитать содержимое в память');
    writeln('3 - показать список книг');
    writeln('4 - поиск книг по заданному году');
    writeln('9 - выход');
    writeLn;
    Write('Введите номер требуемой операции: ');
    ReadLn(M);

    case M of
      1: CreateNewFile(ALLbooks, N, fname); {пункт 1 - создание нового файла данных}
      2: OpenReadFile(ALLbooks, N, fname); {пункт 2 - прочитать файл в память}
      3: ShowList(ALLbooks, N); {пункт 3 - вывести массив с книгами на экран}
      4: begin
          writeln('введите год для поиска: '); readLn(godpoiska);
          Poisk(ALLbooks, N, godpoiska);
        end;
    end; {end of case}
  end; {end of while}
  WriteLn('Bye!');
end.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.11.2013, 10:21   #6
orandzheviyman
Пользователь
 
Регистрация: 11.11.2013
Сообщений: 74
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
да. так можно.
Но я бы рекомендовал, если есть возможность ИЗБАВЛЯТЬСЯ в коде от использования ГЛОБАЛЬНЫХ переменных.

в вашем случае код может выглядеть так (я позволил себе ещё кое-что изменить в вашем коде так, как посчитал нужным ):
Код:
const MAXbook = 100; {максимум книг}
.....
  WriteLn('Bye!');
end.
Cпасибо, на многое в коде открыли мне глаза) А не могли бы вы объяснить как вы оперируете с параметрами процедур?
Код:
write('Использовать имя файла ' + fname + '? (y - да,любой другой символ - нет)');
и что обозначает эта строка?



__________________
Оверквотинг (overquoting) на форуме запрещён.
Не злоупотребляйте избыточным цитированием.
Если Вы отвечаете на предыдущее сообщение, нет необходимости приводить его полностью в своем ответе.
В крайнем случае выберите нужный фрагмент и процитируйте его.
Модератор.

Последний раз редактировалось Serge_Bliznykov; 27.11.2013 в 10:49.
orandzheviyman вне форума Ответить с цитированием
Старый 27.11.2013, 11:07   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Cпасибо, на многое в коде открыли мне глаза)
пожалуйста. Для этого я его и писал!

Цитата:
А не могли бы вы объяснить как вы оперируете с параметрами процедур?
простите, не понял..
Давайте поступим так, вы прочитаете про параметры процедур/функций (в любом учебники или интернете), потом, если вопросы останутся - вы их зададите.
Если вкратце, через параметры мы передаём все необходимые для работы данной процедуры/функции величины. Передаются они с помощью т.н. ФОРМАЛЬНЫХ параметров. указываем имя параметра и его тип. Перед именами допускаются модификаторы var (означает, что параметр передаётся по ссылке и все изменения, внесённые в этот параметер внутри процедуры/функции отразятся на реальном(фактическом) параметре, который мы передадим. Именно с помощью данного модификатора можно обеспечить возвращение нескольких значений из процедуры или функции (функция от процедуры, кстати, отличается только тем, что функция ещё возвращает своё значение, но только одно (одного типа). А указав несколько параметров с модификатором var можно их все вернуть.
Так, например, мы поступаем в процедуре CreateNewFile - данная процедура возвращает не только введённый массив, но и количество элементов в массиве (параметер N) и даже имя файла, куда мы писали данные.
Модификатор const перед именем переменной означает, что внутри процедуры/функции запрещено изменять значение данного параметра.
когда вызываем процедуру/функцию на место формальных параметров подставляем ФАКТИЧЕСКИЕ значения.
Внимание, перечень фактических параметоров должен СТРОГО соответствовать перечню объявленных формальных параметров, как порядок, так и тип и модификатор.
например, если мы объявили формальный FileName типа string с модификатором var, то данную процедуру НЕЛЬЗЯ вызвать, указать строковую константу:
Код:
procedure Example1(var FileName : string);
....
НЕЛЬЗЯ написать
Example1('Имя');
а можно только
var fn : string;
...
 fn := 'Имя'; 
 Example1(fn);
Ну вот, вкратце, и всё



Цитата:
write('Использовать имя файла ' + fname + '? (y - да,любой другой символ - нет)');
и что обозначает эта строка?
мы в процедуру OpenReadFile передаём параметром глобальную переменную, которая хранит имя файла. Если вызвать процедуру открытия файла OpenReadFile после вызова CreateNewFile (мы в этой процедуре задаём имя файла и возвращаем это имя в переменной) или повторно, после вызова OpenReadFile, то в процедуре открытия OpenReadFile мы проверяем эту переменную, если имя уже было задано, мы спросим пользователя, не хочет ли он использовать данное имя.
Это всё просто для облегчения жизни пользователя (чтобы не запоминать имя файла, в который записали значения).
можно и так сделать:
Код:
procedure OpenReadFile(var AB: TBookArray; var N: integer);
var
  f: file of Tbook;
  i: integer;
  locfileName: string
  count: char; {для ввода}

begin
  write('введите имя файла: ');
  readln(locfileName);

  assign(f,  locfileName);
  reset(f);
  N := FileSize(f);
  for i := 1 to N do Read(f, AB[i]);

  writeln;
  WriteLn('Успешно прочитано ', N, ' записей в память.');
  writeln;
  WriteLn('Нажмите ENTER для продолжения');
  Readln;
end;
и вызывать тогда так (обратите внимание, количество параметров изменилось!):
Код:
....
     2: OpenReadFile(ALLbooks, N); {пункт 2 - прочитать файл в память}
 ....
Ещё вопросы есть?!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.11.2013, 12:32   #8
orandzheviyman
Пользователь
 
Регистрация: 11.11.2013
Сообщений: 74
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
пожалуйста. Для этого я его и писал!
Ещё вопросы есть?!
нет, спасибо) очень сильно помогли:3
orandzheviyman вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с записями сергей817 Паскаль, Turbo Pascal, PascalABC.NET 2 24.03.2013 10:06
Работа с записями Falcao Паскаль, Turbo Pascal, PascalABC.NET 6 03.12.2012 23:35
Работа с записями dima-intro Помощь студентам 1 26.12.2010 13:43
Работа с записями Nitriyc Помощь студентам 4 05.12.2009 19:30
Работа с записями Viata Паскаль, Turbo Pascal, PascalABC.NET 3 24.06.2009 09:03