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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 10.05.2010, 17:21   #1
vedro-compota
любитель-далеко не
Участник клуба
 
Аватар для vedro-compota
 
Регистрация: 13.04.2010
Сообщений: 1,156
По умолчанию Сообщение об ошибке при вычислении длины строки

Товарищи, программисты) никак не могу понять- почему делфи
показывает сообщение об ошибке. Я тут что-то вроде калькулятора пишу. Так вот , там в edit1 нужно написать строку, которая является выражением, значение которого необходимо найти (например - "12-2").
Вот код модуля в котором возникает ошибка:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls , holst , sozdereva;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var s,s1: string;
 i,p,k,h:integer;
  uk,uk1:pelement;  
begin
  s:=edit1.text;
  s1:='';
  for i := 1 to length(s) do // уберём пробелы
  if s[i]<>' ' then s1:=s1+s[i];
  label1.Caption:=s1;
  p:=0;// признак закрытия открытой скобки
  k:=0; // признак наличия некорректного ввода
  i:=1;
  while (i<=length(s1)) and (k=0) do // первоначальная проверка корректности .
  begin
    if s1[i]='(' then begin p:=p+1; h:=h+1;
    if (s1[i]=')') and (p<>0) then
    begin
      p:=p-1;
    end;
    if (s1[i]=')') and (p=0) then
    begin
      showmessage(' Нельзя закрывать скобки не открыв их.'+#13#10+'Число открытых и закрытых скобок не совпадает!');
      k:=1; 
    end;
    i:=i+1;
  end;
  if k=1 then
  showmessage('Проверьте корректность введённого выражания.')
  else
  begin
    if p>0 then
    begin
      showmessage ('Скобки не закрыты!');
      showmessage('Проверьте корректность введённого выражания.');
    end;
    k:=1;
  end;
 // canvas.Ellipse(12,23,45,34); // x, y - центр
  uk:=nil;
  uk1:=nil;
  sozdanie(s1,uk1,uk);

end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  form2.Show;
end;

end.
( я выделил ту строку, на которую показывает компилятор при выводе сообщения об ошибке)
Не пойму в чём проблема. Ошибка гласит:
Цитата:
First chance exception at $7664FBAE. Exception class EConvertError with message ''12-2' is not a valid integer value'. Process Project2.exe (4844)
ещё архив прикладываю. ( после запуска необходимо ввести строку и нажать на кнопку "создать дерево"-(просто решение задачи основано на создании дерева, потому такое название))
Вложения
Тип файла: zip 5-5.zip (48.0 Кб, 4 просмотров)
против абортов=за + жизнь;.фкн вгу;_______________________мойблг

Последний раз редактировалось vedro-compota; 10.05.2010 в 19:14. Причина: чтоб понятней было )
vedro-compota вне форума Ответить с цитированием
Старый 10.05.2010, 19:17   #2
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Во-первых, меня смущает строка
Код:
if s1[i]='(' then begin p:=p+1; h:=h+1;
Я не вкупился в код до конца, но кое-чем чую, что должно быть
Код:
if s1[i]='(' then begin p:=p+1; h:=h+1; end;
Соответственно в конце один END надо убрать.

Во-вторых:
Ошибка происходит в модуле sozdereva в строке
Код:
    m:= strtoint (s1);
далее код переходит на except, а за ним цикл
Код:
 while (i<=length(s1)) and (g=0) do
    begin
      if s1[i]=')' then p:=p+1;
      if s1[i]='(' then p:=p-1;
      if (s1[i] in ['-','+']) and (p=0) then
      begin
        g:=1;
        j:=i;
      end;
      if (s1[i]='*') and (p=0) then
      begin
        if s[j]<>'*' then j:=i;
      end;
    end;
где программа благополучно зацикливается, т.к. нет
Код:
i:=i+1;
А еще интуиция подсказывает, что код
Код:
    s:='';
    for i := 1 to j-1 do
    s:=s+s1[i];
    sozdanie (s1,uk1,uk);
нужно исправить на
Код:
    s:='';
    for i := 1 to j-1 do
    s:=s+s1[i];
    sozdanie (s,uk1,uk);
Но это все интуиция, я не до конца вкупился. Короче, будте внимательней и используйте F7
Sibedir вне форума Ответить с цитированием
Старый 10.05.2010, 19:32   #3
vedro-compota
любитель-далеко не
Участник клуба
 
Аватар для vedro-compota
 
Регистрация: 13.04.2010
Сообщений: 1,156
Счастье у вас хорошая интуиция ))

исправил всё, что вы сказали. всё равно лезет ошибка
Цитата:
First chance exception at $7664FBAE. Exception class EConvertError with message ''12-2' is not a valid integer value'. Process Project2.exe (2664)
теперь выделяет "end".
вот так:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls , holst , sozdereva;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var s,s1: string;
 i,p,k,h:integer;
  uk,uk1:pelement;  
begin
  s:=edit1.text;
  s1:='';
  for i := 1 to length(s) do // уберём пробелы
  if s[i]<>' ' then s1:=s1+s[i];
  label1.Caption:=s1;
  p:=0;// признак закрытия открытой скобки
  k:=0; // признак наличия некорректного ввода
  i:=1;
  while (i<=length(s1)) and (k=0) do // первоначальная проверка корректности .
  begin
    if s1[i]='(' then begin p:=p+1; h:=h+1; end;
    if (s1[i]=')') and (p<>0) then
    begin
      p:=p-1;
    end;
    if (s1[i]=')') and (p=0) then
    begin
      showmessage(' Нельзя закрывать скобки не открыв их.'+#13#10+'Число открытых и закрытых скобок не совпадает!');
      k:=1; 
    end;
    i:=i+1;
  end;
  if k=1 then
  showmessage('Проверьте корректность введённого выражания.')
  else
  begin
    if p>0 then
    begin
      showmessage ('Скобки не закрыты!');
      showmessage('Проверьте корректность введённого выражания.');
    end;
    k:=1;
  end;
  uk:=nil;
  uk1:=nil;
  sozdanie(s1,uk1,uk);

end;


procedure TForm1.Button2Click(Sender: TObject);
begin
  form2.Show;
  form2.canvas.Ellipse(500-25,30-25,500+25,30+25);
end;

end.
почему же возникает ошибка?
(прикладываю "исправленный архив")
Вложения
Тип файла: zip 5-5-1.zip (54.7 Кб, 6 просмотров)
против абортов=за + жизнь;.фкн вгу;_______________________мойблг
vedro-compota вне форума Ответить с цитированием
Старый 10.05.2010, 19:50   #4
Sibedir
Тот ещё
Старожил
 
Аватар для Sibedir
 
Регистрация: 14.11.2007
Сообщений: 2,242
По умолчанию

Поймите же, у вас ошибка возникает не в той строке, которая подсвечивается красным (научитесь пользоваться F7). И виной тому структура
Код:
try
except
end;
Используя подобную структуры, вы как бы говорите компилятору: "Эй чувак, я крутой парень и за свои ошибки буду отвечать сам." И по сути вы так и делаете. Только делаете это совсем не к месту. Ведь на except программа перейдет в случае любой ошибки, даже не заплонированной вами.
Я предлагаю вам использовать процедуру Val. Почитайте. Думаю вас это устроит.
Sibedir вне форума Ответить с цитированием
Старый 10.05.2010, 21:17   #5
vedro-compota
любитель-далеко не
Участник клуба
 
Аватар для vedro-compota
 
Регистрация: 13.04.2010
Сообщений: 1,156
По умолчанию но

но ведь я отвечаю только за ошибки между try и except, то есть в дополнительном модуле :
Код:
Try
    m:= strtoint (s1);
    new(uk0);
    if uk<>nil then
    begin
      if uk^.left=nil then uk^.left:=uk0 else
      uk^.right:=uk0;
    end;
    uk0^.infa:=s1;
    if uk1=nil then uk1:=uk0;
    uk0^.left:=nil;
    uk0^.right:=nil;
  except
разве не так? )
против абортов=за + жизнь;.фкн вгу;_______________________мойблг
vedro-compota вне форума Ответить с цитированием
Старый 10.05.2010, 22:13   #6
vedro-compota
любитель-далеко не
Участник клуба
 
Аватар для vedro-compota
 
Регистрация: 13.04.2010
Сообщений: 1,156
По умолчанию и

да и текст ошибки.....как раз от том, что должно игнорироваться. кто подскажет. Проверяю как и сказали - пошагово, программа вылетает как раз на строке:
Код:
m:= strtoint (s1);
в модуле sozdereva.pas.
Код:
unit sozdereva;

interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls , holst;
type
  pelement= ^telement;
  Telement= record
    infa: string;
    left,right:pelement;
  end;
procedure sozdanie (var s: string; uk1,uk: pelement);
implementation
procedure sozdanie (var s: string; uk1,uk: pelement);
var
    s1: string;
    i,p,g,j,m:integer;
    uk0:pelement;
begin
  {Для начала необходимо найти в строке символ,
  обозначающий действие, которое выполниться последним.
  для этого следует анализировать порядок расстановки скобок.
  При этом очень хорошо было бы избавиться от  не несущих никакой
  информации внешних скобок, что мы и сделаем первым циклом}
  if (s[1]='(') and (s[length(s)]=')')  then
  for i := 2 to length(s)-1  do
  s1[i-1]:=s[i]
  else
  s1:=s;
  {теперь мы просто должны найти знак,
  обозначающий действие меньшего приоритета
  в той области выражения,где число открытых скобок
  равно числу закрытых,имеет смысл начать поиск
  с конца выражения(это сэкономит бесценное время;))
  Соответственно, если это знак + или знак - , то мы
  заканчиваем поиск, если же это * ,то мы продолжаем поиск
  пока не дойдём до начала скроки-выражения.}
  i:=1;
  g:=0;
  j:=1;
  p:=0;
  Try
    m:= strtoint (s1);
    new(uk0);
    if uk<>nil then
    begin
      if uk^.left=nil then uk^.left:=uk0 else
      uk^.right:=uk0;
    end;
    uk0^.infa:=s1;
    if uk1=nil then uk1:=uk0;
    uk0^.left:=nil;
    uk0^.right:=nil;
  except
    i:=length(s1);
    while (i>=1) and (g=0) do  // эти циклом определим действие, которое буде выполняться последним
    begin
      if s1[i]=')' then p:=p+1;
      if s1[i]='(' then p:=p-1;
      if (s1[i] in ['-','+']) and (p=0) then
      begin
        g:=1;
        j:=i;
      end;
      if (s1[i]='*') and (p=0) then
      begin
        if s[j]<>'*' then j:=i;
      end;
      i:=i-1;
    end;
    new(uk0);
    if uk<>nil then
    begin
      if uk^.left=nil then uk^.left:=uk0 else
      uk^.right:=uk0;
    end;
    uk0^.infa:=s1[j];
    if uk1=nil then uk1:=uk0;
    uk:=uk0;
    uk^.left:=nil;
    s:='';
    for i := 1 to j-1 do
    s:=s+s1[i];
    sozdanie (s,uk1,uk);
    for i := j+1 to length(s1) do
    s:=s+s1[i];
    sozdanie (s,uk1,uk);
  end;

end;

end.
а ведь структура try except как раз и призвана обойти эту ошибку ( операция не всегда будет ошибочной).
Прости за несообразительность, но не понимаю , что не так. ))
Помогите, кто чем может 0)))
против абортов=за + жизнь;.фкн вгу;_______________________мойблг
vedro-compota вне форума Ответить с цитированием
Старый 10.05.2010, 23:40   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Цитата:
а ведь структура try except как раз и призвана обойти эту ошибку
Ничего она не обходит. А только говорит: если тут будет эта ошибка, то сделай это.

Цитата:
но не понимаю , что не так. ))
А вы подумайте, какое число представляется строкой
Цитата:
(например - "12-2")
? А 1р3?
p51x вне форума Ответить с цитированием
Старый 11.05.2010, 07:54   #8
vedro-compota
любитель-далеко не
Участник клуба
 
Аватар для vedro-compota
 
Регистрация: 13.04.2010
Сообщений: 1,156
По умолчанию мммм.....

Цитата:
Ничего она не обходит. А только говорит: если тут будет эта ошибка, то сделай это.
1) то есть сообщение об ошибке появляется в любом случае, да?
2) Странно, что компилятор не выделяет ту строку,где ошибка....
вот
против абортов=за + жизнь;.фкн вгу;_______________________мойблг
vedro-compota вне форума Ответить с цитированием
Старый 11.05.2010, 07:58   #9
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
Сообщение от vedro-compota Посмотреть сообщение
2) Странно, что компилятор не выделяет ту строку,где ошибка....
вот
Он не может отследить некоторые моменты. Особенно видно при работе с БД. Ошибку увидели? То, что Вы пытаетесь преобразовать числом не является (а в данном случае должно). Кроме того, есть функции которые преобразовывают строку в любом случае без выдачи исключения.
Посмотрите TryStrToInt
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика

Последний раз редактировалось Utkin; 11.05.2010 в 08:02.
Utkin вне форума Ответить с цитированием
Старый 11.05.2010, 08:17   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Странно, что компилятор не выделяет ту строку
Ниче странного. Ошибка может вылезти внутри кода операторов строки, потому редактор и не покажет где именно.
Кроме вышесказанного уткиным рекомендую еще процедуру val, которая не выкинет ошибку при несоответствии строки для конвертирования.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сообщение об ошибке ruavia3 Microsoft Office Excel 3 13.10.2009 23:10
Сообщение об ошибке Kreadlling Общие вопросы C/C++ 3 08.09.2009 13:30
Сообщение об ошибке! QWERT1988 Общие вопросы Delphi 4 01.06.2009 17:14
Сообщение об ошибке при вводе неверного типа информации в DBEdit megaten БД в Delphi 6 17.05.2009 20:44
Перехватить сообщение об ошибке Insainer Общие вопросы Delphi 5 25.04.2008 20:39