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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.05.2016, 17:33   #1
artems67
Пользователь
 
Регистрация: 17.11.2015
Сообщений: 62
Восклицание [Free Pascal] Проблема с нетипизированным файлом

Здравствуйте,

Условие задачи:

1. Часть

Описать структуру с именем NOTE, содержащую следующие поля:
  • Фамилия имя
  • номер телефона
  • дата рождения (массив из 3-х чисел)
Написать программу выполняющие следующие действия:
  • ввод с клавиатуры данных в массив, состоящий из 8 элементов типа NOTE (записи должны быть упорядочены по дате рождения)
  • вывод на экран информации о человеке, номер телефона которого введен с клавиатуры (если такого нет, вывести сообшение об ошибке)
2.Часть
Вводимые данные нужно сохранить в нетипизрованном файле, а при запросе информации о человеке её нужно считать из этого же файла и вывести на экран.

Суть проблемы

Дело в том, что этот код (см.ниже) я писал в PascalABCNET. И там данная программа работает приемлимо. Компиляцию проходит, данные в файл записываются.

Но дело в том, что на занятиях мы работаем в FreePascal. И когда я пробую данный код открыть в FreePascal он ругается при компиляции и выводит ошибку: Can't use read or write on untyped file

Может кто-то сможет мне разъяснить в чем у меня заключается проблема и поможет найти решение. Буду премного благодарен.

Код программы:

Код:
Program Pr_3;
uses crt;

type NOTE=record
  godr:record
    ch:Byte;
    m:Byte;
    g:integer;
  END;
    FI:string[45];
    tel:Longint;
  END;
     mas1=array[1..25] of NOTE;

label new,q,z;
VAR a,b:mas1;
    i,n,k,j:integer;
    nomer:Longint;
    f1:file;

begin
clrscr;
assign(f1, 'd:\My_ArhivS\PASCAL_FILES\NOTE_RUS\a.NOTE');

{Кол-во элементов массива}
write('Кол-во сотрудников: '); 
  readln(n);
writeln;

{Заполнение полей записи в массиве}
for i:=1 to n do
  begin
    write('Фамилия Имя: ');
     readln(a[i].FI);
    write('Телефон: ');
     readln(a[i].tel);
    write('Дата Рождения (через пробел): ');
     readln(a[i].godr.ch,a[i].godr.m,a[i].godr.g);
   end;
   
clrscr;

{Сортировка элементов массива по дате рождения}
 for i := 1 to n-1 do
        for j := 1 to n-i do
            if a[j].godr.g > a[j+1].godr.g then begin
                k := a[j].godr.g;
                a[j].godr.g:= a[j+1].godr.g;
                a[j+1].godr.g:= k;
            end;
            
{Запись отсортированных данных в файл}
rewrite(f1);     
for i:=1 to n do 
  begin
    write(f1,a[i].FI);
    write(f1,a[i].tel);
    write(f1,a[i].godr.ch,a[i].godr.m,a[i].godr.g);
  end;

new:  
writeln;
write('Введите номер телефона: ');
  readln(nomer);

reset(f1);
for i:=1 to n do begin
  read(f1,b[i].FI);
  read(f1,b[i].tel);
  read(f1,b[i].godr.ch,b[i].godr.m,b[i].godr.g);
  if nomer <> b[i].tel then goto z 
  else begin 
        write(b[i].FI,' ');
        write(b[i].tel,' ');
        write(b[i].godr.ch,'.',b[i].godr.m,'.',b[i].godr.g);
        goto q;
        z:
        if i = 5 then 
          begin
           writeln('Ошибка!');
           goto new;
          end;
       end; 
   end;
q:
close(f1);
readln;
END.
artems67 вне форума Ответить с цитированием
Старый 21.05.2016, 18:02   #2
FPaul
Форумчанин
 
Регистрация: 25.01.2015
Сообщений: 472
По умолчанию

почитайте о расширенном формате reset / rewrite, и о процедурах чтения / записи BlockRead / BlockWrite
http://pascal.net.ru/%D0%97%D0%B0%D0...%D1%8B+%285%29
FPaul вне форума Ответить с цитированием
Старый 29.05.2016, 20:42   #3
artems67
Пользователь
 
Регистрация: 17.11.2015
Сообщений: 62
Печаль

Цитата:
Сообщение от FPaul Посмотреть сообщение
почитайте о расширенном формате reset / rewrite, и о процедурах чтения / записи BlockRead / BlockWrite
http://pascal.net.ru/%D0%97%D0%B0%D0...%D1%8B+%285%29
UPD:

Попытался кое-как вникнуть в статью, спасибо. НО...

После заполнения n-го кол-ва анкет работников во время записи данных в нетипизированный файл выскакивает ошибка exitcode = 1748.

Честно, до конца специфику буфера и count не понял. По этой теме очень мало инфы в интернете, в частности применение нетепизированных файлов на практике.

обновленный код программы:

Код:
Program Pr_3;
uses crt;

type NOTE=record
  godr:record
    ch:Byte;
    m:Byte;
    g:integer;
  END;
    FI:string[45];
    tel:Longint;
  END;
     mas1=array[1..25] of NOTE;

label new,q,z;
VAR a,b:mas1;
    BufLen:integer;
    NumRead, NumWritten:word;
    i,n,k,j:integer;
    nomer:Longint;
    f1:file;

begin
clrscr;
assign(f1, 'd:\My_ArhivS\PASCAL_FILES\NOTE_ENG\a.NOTE');

{Kol-vo elementov massiva}
write('Kol-vo sotrudnikov: ');
  readln(n);
writeln;

{Zapolnenie polei zapisi v massive}
for i:=1 to n do
  begin
    write('FI*: ');
     readln(a[i].FI);
    write('telephon: ');
     readln(a[i].tel);
    write('Data rojdenia* (cherez probel): ');
     readln(a[i].godr.ch,a[i].godr.m,a[i].godr.g);
   end;

clrscr;

{Sortirovka elementov metodom pyzirka*}
 for i := 1 to n-1 do
        for j := 1 to n-i do
            if a[j].godr.g > a[j+1].godr.g then begin
                k := a[j].godr.g;
                a[j].godr.g:= a[j+1].godr.g;
                a[j+1].godr.g:= k;
            end;

{Zapis dannix v fail}
BufLen:=SizeOf(a);
rewrite(f1,BufLen);
BlockWrite(f1,a,BufLen);
close(f1);

{Poisk rabotnika po nomery}
new:
writeln;
write('Vvedite nomer telephona: ');
  readln(nomer);

{Chtenie dannix iz faila}
reset(f1,BufLen);
blockread(f1,b,BufLen);

{Poisk rabotnika po nomery}
for i:=1 to n do begin
  if nomer <> b[i].tel then goto z
  else begin
        write(b[i].FI,' ');
        write(b[i].tel,' ');
        write(b[i].godr.ch,'.',b[i].godr.m,'.',b[i].godr.g);
        goto q;
        z:
        if i = 5 then
          begin
           writeln('Error! Try again!');
           goto new;
          end;
       end;
   end;
q:
close(f1);
readln;
END.

Последний раз редактировалось artems67; 29.05.2016 в 20:48.
artems67 вне форума Ответить с цитированием
Старый 29.05.2016, 20:50   #4
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Код:
 f1:text;
не вариант?
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 29.05.2016, 21:09   #5
artems67
Пользователь
 
Регистрация: 17.11.2015
Сообщений: 62
По умолчанию

Цитата:
Сообщение от Aleksandr H. Посмотреть сообщение
Код:
 f1:text;
не вариант?
См. шапку темы. В работе исключительно нетепизированный файл. Другие типы файлов у меня не вызывают трудностей.

UPD:

Уря заработало! Но все равно некоторые вещи остались недопонятыми. Я так понял в rewrite/reset указывается размер одной записи. rewrite(f1,BufLen); Buflen = размер буфера, т.е. массива a.

Но в BlockRead/BlockWrite по идеи указывается количество записей этого размера. BlockWrite(f1,a,1); Я так понял это и есть то самое count. Но почему 1 (эту цифру я подобрал методом тыка) ? Если у меня n кол-во работников. Почему програ проглатывает только эту цифру. Если скажем у меня работников 5 (n=5). В учебниках вообще предлагают какую-то переменную типа word ставить. С ней тоже ошибка.

Код программы:

Код:
Program Pr_3;
uses crt;

type NOTE=record
  godr:record
    ch:Byte;
    m:Byte;
    g:integer;
  END;
    FI:string[45];
    tel:Longint;
  END;
     mas1=array[1..25] of NOTE;

label new,q,z;
VAR a,b:mas1;
    BufLen:integer;
    NumRead, NumWritten:word;
    i,n,k,j:integer;
    nomer:Longint;
    f1:file;

begin
clrscr;
assign(f1, 'd:\My_ArhivS\PASCAL_FILES\NOTE_ENG\a.NOTE');

{Kol-vo elementov massiva}
write('Kol-vo sotrudnikov: ');
  readln(n);
writeln;

{Zapolnenie polei zapisi v massive}
for i:=1 to n do
  begin
    write('FI*: ');
     readln(a[i].FI);
    write('telephon: ');
     readln(a[i].tel);
    write('Data rojdenia* (cherez probel): ');
     readln(a[i].godr.ch,a[i].godr.m,a[i].godr.g);
   end;

clrscr;

{Sortirovka elementov metodom pyzirka*}
 for i := 1 to n-1 do
        for j := 1 to n-i do
            if a[j].godr.g > a[j+1].godr.g then begin
                k := a[j].godr.g;
                a[j].godr.g:= a[j+1].godr.g;
                a[j+1].godr.g:= k;
            end;

{Zapis dannix v fail}
BufLen:=SizeOf(a);
rewrite(f1,BufLen);
BlockWrite(f1,a,1);
close(f1);

{Chtenie dannix iz faila}
reset(f1,BufLen);
blockread(f1,b,1);

new:
writeln;
write('Vvedite nomer telephona: ');
  readln(nomer);

for i:=1 to n do begin
  if nomer <> b[i].tel then goto z
  else begin
        write(b[i].FI,' ');
        write(b[i].tel,' ');
        write(b[i].godr.ch,'.',b[i].godr.m,'.',b[i].godr.g);
        goto q;
        if i = 5 then
          begin
           z:
           writeln('Error! Try again!');
           goto new;
          end;
       end;
   end;
q:
close(f1);
readln;
END.

Последний раз редактировалось artems67; 29.05.2016 в 21:15.
artems67 вне форума Ответить с цитированием
Старый 29.05.2016, 22:04   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Но почему 1 (эту цифру я подобрал методом тыка) ?
потому что переменная a у Вас - это МАССИВ, размером 25 записей.
и программе абсолютно всё равно, какое у Вас N (хоть 5, хоть 10, хоть 25),
т.к. в файл записывается сразу ВЕСЬ МАССИВ.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 29.05.2016, 23:37   #7
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,309
По умолчанию

Цитата:
Честно, до конца специфику буфера и count не понял. По этой теме очень мало инфы в интернете, в частности применение нетепизированных файлов на практике.
Не буду оригиналом и посоветую учебник (имеется в списке литературы) Т.А. Павловская , Программирование на ЯВУ.
В разделе по работе с файлами есть простые и понятные примеры.

Как-то так, ...
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 29.05.2016, 23:48   #8
artems67
Пользователь
 
Регистрация: 17.11.2015
Сообщений: 62
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
потому что переменная a у Вас - это МАССИВ, размером 25 записей.
и программе абсолютно всё равно, какое у Вас N (хоть 5, хоть 10, хоть 25),
т.к. в файл записывается сразу ВЕСЬ МАССИВ.
Понятно, а я думал, что наоборот это число указывает сколько записей из массива записать в файл. То есть цифра 1 = 1 запись из массива. Следовательно данные только одного сотрудника можно вывести на экран. Именно это мне порвало шаблон. Но я ошибся.

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

Как-то так, ...
Спасибо, обязательно ознакомлюсь.
artems67 вне форума Ответить с цитированием
Старый 30.05.2016, 09:49   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Понятно, а я думал, что наоборот это число указывает сколько записей из массива записать в файл. То есть цифра 1 = 1 запись из массива.
Нет. Вы, когда открываете нетипизированный файл, задаёте размер одной записи (блока) обращения к файлу. Размер блока, кстати, задаётся в байтах.
Reset(f,1); означает - читать по одному байту
Reset(f,256); означает - читать по 256 байт за одну операцию ввода/вывода.

BlockRead/BlockWrite - указываем сколько БЛОКОВ (размера, заданного при открытии файла) нужно прочитать/записать.

Ну и ещё. Операции BlockRead / BlockWrite совсем не обязательно работают с массивом. Они позволяют использовать переменную ЛЮБОГО типа.
Хоть integer, хоть string, хоть boolean, хоть Record. Хотя, при этом важно знать, как эта самая переменная хранится в памяти (особенно важно для переменной типа String). в самом простом и общем случае размер блока обращения к файлу ставят размером в 1 байт и при чтении/записи использую SizeOf(переменная) - размер, который занимает переменная в памяти.

p.s. а теорию почитайте, полезно!
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задание с нетипизированным файлом Василий15 Паскаль, Turbo Pascal, PascalABC.NET 17 12.05.2016 00:14
Валютные операции в pascal - Free Pascal leonix12 Lazarus, Free Pascal, CodeTyphon 2 10.04.2016 12:37
Turbo Pascal и Free Pascal , в чем разница? antoxann Паскаль, Turbo Pascal, PascalABC.NET 31 09.11.2011 07:52
Проблема с Free Pascal. Paster Fob Паскаль, Turbo Pascal, PascalABC.NET 2 22.02.2011 22:25
а free pascal не читает задачи которые написаны на turbo pascal? demonara Паскаль, Turbo Pascal, PascalABC.NET 3 25.05.2009 16:28