LINUX.ORG.RU

fpc, не собирается старый код

 


0

2

Добрый день. Прошу прощения за нубский вопрос (ответ наверняка элементарный), только не знаю как правильно дёрнуть гугель за язык.

Код (из учебника, 1984й Оруэлла год):

const
  SPACE = ' ';
var
  ch: char;
begin
  while input^ = space do
    read(ch);
  while input^ <> space do
    begin
      read(ch);
      write(ch);
    end;
end.

Ответ компилятора:

copyword.pas(9,15) Error: Illegal qualifier

Ответ на: комментарий от sf
Специальный тип файла - Текстовый файл (Text), представленный записью
TextRec. Файлы текстового (Text) типа используют специальные
подпрограммы ввода – вывода. Файловые типы Input, Output и StdErr
определены в модуле system: они все текстового типа (Text), и
открываются в коде инициализации модуля system.

-- Справочное руководство по FreePascal, 3.3.4 "Файловый тип"
tt
() автор топика
Ответ на: комментарий от tt

В твоей цитате в принципе говорится про файловые типы, а не переменные. Но возможно это косяк в документации (а сам я не помню уже).

Но в тексте ошибки у тебя вообще-то написано не про ненайденный идентификатор переменной, а про неверный квалификатор. И тут вопрос: разве оператор ^ применим к файловым переменным? Это же вроде была работа с указателями

kss ★★★★★
()
Ответ на: комментарий от kss

Теоретически, это попытка реализовать символьный i/o (k&r, глава 1.5): считать символ с консоли и выплюнуть обратно юзверю. Весь вопрос – как это сделать на современном паскале?

Насчёт работы с указателями не знаю, пока просто не добрался до них.

tt
() автор топика

Надо смотреть как там устроен TextRec внутри, думаю будет чтото вроде такого:

const
  SPACE=' ';
function GetByte(var t:Text):char;
begin
  if TextRec(t).BufPos>=TextRec(t).BufEnd then
    result:=#0
  else
    result:=TextRec(t).Bufptr^[TextRec(t).BufPos];
end;
var
  ch: char;
begin
  while GetByte(input) = space do
    read(ch);
  while GetByte(input) <> space do
    begin
      read(ch);
      write(ch);
    end;
end.
zamtmn ★★
()
Ответ на: комментарий от kss

У Вирта это был доступ к данным файла по текущему файловому указателю (согласитесь, определённая логика в этом есть).
На сегодняшний день я не знаю трансляторов паскаля, которые поддерживали бы этот синтаксис.

bormant ★★★★★
()
Ответ на: комментарий от tt

Только не result := #0, a GetByte := #0.

Если говорить о Free Pascal, то
https://www.freepascal.org/docs-html/ref/refse94.html

В двух словах, в режимах ObjFPC и Delphi ({$mode ObjFPC}, {$mode Delphi}) помимо ИмяФункции:=значение доступен синтаксис возврата значения
а) через Result:=значение и
б) через Exit(значение).

Что касается предложения @zamtmn, на старте программы (а равно и сразу после Reset(TextFile)) буфер файла еще пуст:

begin with TextRec(input) do begin
  WriteLn('BufPos: ',BufPos,', BufEnd: ',BufEnd);  // BufPos: 0, BufEnd: 0
end; end.
то есть идея подсмотреть символ в буфере файловой переменной не сработает, точнее не сработает довольно часто.

Нужно строить алгоритмы исходя из других предположений, в том числе из того, что посмотреть в содержимое файла без его чтения нельзя. Но пропустить незначащие символы в потоке можно по SeekEoLn(), SeekEoF().

bormant ★★★★★
()
Ответ на: комментарий от zamtmn

Лучше как-то так:

type
  FileFunc = procedure(var t: TextRec);

function PeekChar(var t: Text): Char;
begin with TextRec(t) do begin
  PeekChar:=#0;
  if InOutRes<>0 then Exit;
  if mode<>fmInput then Exit;
  if BufPos>=BufEnd then begin
    FileFunc(InOutFunc)(TextRec(t));
    if BufPos>=BufEnd then Exit;
  end;
  PeekChar:=BufPtr^[BufPos];
end; end;

bormant ★★★★★
()
program copyword (input, output);
const
  SPACE = ' ';
var
  ch: char;
begin
  while input^ = space do
    read(ch);
  while input^ <> space do
    begin
      read(ch);
      write(ch);
    end;
end.
$ fpc -Miso copyword.pas 
Free Pascal Compiler version 3.2.0 [2020/06/27] for x86_64
Copyright (c) 1993-2020 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling copyword.pas
Linking copyword
14 lines compiled, 0.1 sec
$ 
iliyap ★★★★★
()