Баг или моя ошибка?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Баг или моя ошибка?

Сообщение Paster Fob » 20.03.2013 11:33:48

Вот такой код вылетает с ошибкой:
Код: Выделить всё
var
  s:string;

begin
  s:='   ';
  while (s[1]=' ') and (length(s)>0) do
    delete(s,1,1);
end.


меняю местами логические условия и тогда всё нормально.
Код: Выделить всё
var
  s:string;

begin
  s:='   ';
  while  (length(s)>0) and (s[1]=' ') do
    delete(s,1,1);
end.

Это баг или что?В FPC,TP,PascalABC оба варианта работают нормально.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Баг или моя ошибка?

Сообщение alexs » 20.03.2013 12:12:17

второе верно. первое нет.
условия проверяются слева на право.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4064
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Баг или моя ошибка?

Сообщение Sergei I. Gorelkin » 20.03.2013 12:13:14

Тип переменной S управляется опцией {$H+}, в FPC и TP она по умолчанию отключена и s имеет тип shortstring, в Lazarus - наоборот, включена, и s имеет тип ansistring.
Если тип s shortstring, то ее память постоянно выделена и обращение к элементам не вызывает ошибок. Если ansistring, то память выделена только если строка не пустая - соответственно попытка чтения символа из пустой строки приведет к падению.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Баг или моя ошибка?

Сообщение Paster Fob » 21.03.2013 07:00:31

Ясно,спасибо что разъяснили.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Баг или моя ошибка?

Сообщение Vadim » 21.03.2013 13:37:19

Paster Fob
Чтобы было ещё более понятно, можете результат Ваших действий визуализировать:
Код: Выделить всё
var
  s:string;

begin
  s:='   ';
  n:=0;
  while (s[1]=' ') and (length(s)>0) do
  Begin
    Inc(n);
    WriteLn('Действие ', n, ':');
    WriteLn('Длина строки до удаления: ', Length(s));
    delete(s,1,1);
    WriteLn('Длина строки после удаления: ', Length(s));
  End;
end.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Баг или моя ошибка?

Сообщение Paster Fob » 09.04.2013 11:27:09

Программа подсчитывает кол-во слов в собственном коде.

Программа вылетает с ошибкой,в процедуре FindWord на строке if aword=p^.mword then begin .В Delphi , FPC всё работает.В чём проблема?
Код: Выделить всё
const
  Sym=['A'..'Z'];

type
  prec=^trec;
  trec=record
    mword:string;
    mcount:byte;
    mnext:prec;
  end;

var
  list:prec;

procedure AddToSortList(const aword:string);
var
  p,q:prec;
begin
  new(p);
  p^.mword:=aword;
  p^.mcount:=1;
  q:=list;
  if not assigned(list) then list:=p
  else begin
    while (assigned(q^.mnext)) and (q^.mnext^.mword<aword) do
      q:=q^.mnext;
    if q^.mword>aword then begin
      p^.mnext:=list;
      list:=p;
    end
    else begin
      p^.mnext:=q^.mnext;
      q^.mnext:=p;
    end;
  end;
end;

procedure FindWord(const aword:string);
var
  p:prec;
begin
  p:=list;
  while assigned(p) do begin
    if aword=p^.mword then begin
      inc(p^.mcount);
      break;
    end;
    p:=p^.mnext;
  end;
  if not (assigned(p)) then
    AddToSortList(aword)
end;

procedure ProcessLine(var arg:string);
var
  s:string;
  i:byte;
begin
  for i:=1 to length(arg) do
    arg[i]:=UpCase(arg[i]);
  while length(arg)>0 do begin
    s:='';
    while (length(arg)>0) and not (arg[1] in Sym) do
      delete(arg,1,1);
    while (length(arg)>0) and (arg[1] in Sym) do begin
      s:=s+arg[1];
      delete(arg,1,1);
    end;
    if length(s)>1 then
      FindWord(s);
  end;
end;

procedure PrintList;
var
  p:prec;
begin
  p:=list;
  while assigned(p) do begin
    writeln(p^.mword,p^.mcount:20-length(p^.mword) );
    p:=p^.mnext;
  end;
end;

var
  f:text;
  s,st:string;
  i:byte;

begin
  assign(f,'C:\Programm Pascal\my programs\P_55_1_1.pas');
  reset(f);
  list:=nil;
  while not eof(f) do begin
    readln(f,s);
    ProcessLine(s);
  end;
  close(f);
  PrintList;
  readln;
end.
Аватара пользователя
Paster Fob
постоялец
 
Сообщения: 188
Зарегистрирован: 22.02.2011 21:53:36
Откуда: Новосибирск.

Re: Баг или моя ошибка?

Сообщение SeZuka » 09.04.2013 12:08:31

А попроще алгоритм нельзя было придумать?
И почему в конце не освобождаете память от того что туда напихали?
Ну а по сути, у вас не хватает инициализации поля в записи (указателя на следующую запись):
p^.mnext:=nil;
в процедуре AddToSortList
Код: Выделить всё
procedure AddToSortList(const aword:string);
var
  p,q:prec;
begin
  new(p);
  p^.mword:=aword;
  p^.mcount:=1;
  p^.mnext:=nil; // добавьте
  q:=list;
SeZuka
постоялец
 
Сообщения: 209
Зарегистрирован: 05.09.2012 14:58:05


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 235

Рейтинг@Mail.ru
cron