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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.11.2011, 20:43   #1
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
По умолчанию Invalid Pointer operation

Не работаете прога для вычисления простых чисел.
Busy, Canceled и CanceledExit - переменные типа boolean.

Код:
   function checksimple(i: integer): boolean;
   var j:integer;
   begin
        if i<=1 then
           begin
           result:=false;
           Exit;
           end;
        for j:=2 to i-1 do
            begin
            if i mod j=0 then
               begin
               result:=false;
               Exit;
               end;
            end;
        result:=true;
   end;

   function IsNumberOnly(s:string):boolean;
   var
     i,j:byte;
     res:array of boolean;
   begin
     SetLength(res,Length(s));
     for i:=1 to Length(res) do res[i]:=false;
     //îáíóëÿåì ìàññèâ
     for i:=1 to Length(s) do
         for j:=0 to 9 do
             if s[i] = IntToStr(j) then
                begin
                res[i]:=true;
                end;

     for i:=1 to Length(res) do
         if res[i]=false then
            begin
            result:=false;
            Exit;
            end;
     result:=true;
   end;
//   function FloatToInt
begin
     if IsNumberOnly(min.Text)=false then
        begin
        MessageBoxEx(Form1.Handle, PChar('Ðàçðåøåíû òîëüêî öèôðû!'), PChar('Îøèáêà'), MB_OK+MB_ICONSTOP, LiD);
        min.SetFocus;
        Exit;
        end;
     if NOT IsNumberOnly(max.Text)=false then
        begin
        MessageBoxEx(Form1.Handle, PChar('Ðàçðåøåíû òîëüêî öèôðû!'), PChar('Îøèáêà'), MB_OK+MB_ICONSTOP, LiD);
        max.SetFocus;
        Exit;
        end;
     min_:=StrToInt(min.Text);
     max_:=StrToInt(max.Text);
//     Initialize(min__,max__);
     min__:=min_; max__:=max_;
{}{}{}{}{}     ProgressBar1.Min:=min__;
     ProgressBar1.Max:=max__;
//     Finalize(min__,max__);
     Canceled:=false; CanceledExit:=false; Busy:=true;

     if v_fajl.Text='' then
        begin
        MessageBoxEx(Form1.Handle, PChar('Íå çàïèñàí ïóòü ê ôàéëó!'), PChar('Îøèáêà'), MB_OK+MB_ICONSTOP, LiD);
        Exit;
        end;
     Button1.Enabled:=false;
     ButtonCancel.Enabled:=true;
     Assignfile(f,v_fajl.Text);
     Rewrite(f);
     crs:=Screen.Cursor;
     Screen.Cursor:=crHourgLass;
     i:=min_; ProcessLabel.Caption:='0% 0 èç '+IntToStr(max_)+' îáðàáîòàíî';
     while i<>max_ do
         begin
         if checksimple(i) then Writeln(f,i);
         ProgressBar1.Position:=i;
         i:=i+1;
         Percent:=FloatToStr(Int( i*100/max_ ))+','+Copy(FloatToStr(Frac( i*100/max_ )),3,1)+'% ';
         if Percent[Length(Percent)-2]=',' then Delete(Percent,Length(percent)-2,1);
         ProcessLabel.Caption:=Percent+IntToStr(i-min_)+' èç '+IntToStr(max_-min_)+' îáðàáîòàíî';
         Application.ProcessMessages;
         if Canceled then break;
         end;
     Closefile(f);
     Screen.Cursor:=crs;
     if NOT Canceled then MessageBoxEx(Form1.Handle, PChar('Âû÷èñëåíèå ïðîñòûõ ÷èñåë âûïîëíåíî'), PChar('Ãîòîâî'), MB_OK+MB_ICONINFORMATION, LiD)
                     else MessageBoxEx(Form1.Handle, PChar('Âû÷èñëåíèå ïðîñòûõ ÷èñåë ÏÐÅÐÂÀÍÎ'), PChar('Ãîòîâî'), MB_OK+MB_ICONINFORMATION, LiD);
     Button1.Enabled:=true; ButtonCancel.Enabled:=false; Busy:=false;
     if CanceledExit then Close;
end;
hon вне форума Ответить с цитированием
Старый 21.11.2011, 22:17   #2
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Не код, а кошмар (( где Вы его взяли ?
Код:
function IsNumberOnly(s:string):boolean;
   var
     i,j:byte;
     res:array of boolean;
   begin
     SetLength(res,Length(s));
     for i:=1 to Length(res) do res[i]:=false;
     //îáíóëÿåì ìàññèâ
     for i:=1 to Length(s) do
         for j:=0 to 9 do
             if s[i] = IntToStr(j) then
                begin
                res[i]:=true;
                end;

     for i:=1 to Length(res) do
         if res[i]=false then
            begin
            result:=false;
            Exit;
            end;
     result:=true;
   end;
всё тело функции легко заменяется на примитивнейший
Код:
result := true;
for i := 1 to length(s) do
  if not (s[i] in ['0'..'9']) then // если in не нравится, то заменить на if (s[i]<'0') and (s[i]>'9')
    begin
    result := false;
    exit;
    end;
Главный ход программы, кстати, непонятно, к чему он относится - код принадлежит форме, но не указан никакой метод, хотя бы клик по кнопке; так вот, главный ход - мешанина из всяких обращений к контролам и обработка их данных. Разнесите по отдельным методам - удобнее будет, может и ошибка будет локализована.

Ошибка, мне кажется, кроется в фееричной обработке вычислений процентов, там понапихано и строки и переводы из строк и обратно, и удаление символов и ещё кое-что. Советую не мудрить, а единожды вычислить процент в виде дробного числа и уже потом присвоить его с округлением в прогреслейбл, например как-то так:
Код:
ProcessLabel.Caption:= inttostr(trunc(i*100/max_))+IntToStr(i-min_)+' èç '+IntToStr(max_-min_)+' îáðàáîòàíî';
Ну, по крайней мере, Вы не указали где среда указывает на ошибку, а вроде иных камней я не вижу.
Надо сказать , сама функция проверки на простоту вопросов не вызвала )
phomm вне форума Ответить с цитированием
Старый 22.11.2011, 04:49   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

http://www.gunsmoker.ru/2011/01/blog-post.html
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 22.11.2011, 21:46   #4
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Не код, а кошмар (( где Вы его взяли ?
(код)
всё тело функции легко заменяется на примитивнейший
Код:
result := true;
for i := 1 to length(s) do
  if not (s[i] in ['0'..'9']) then // если in не нравится, то заменить на if (s[i]<'0') and (s[i]>'9')
    begin
    result := false;
    exit;
    end;
Советую так:
Код:
ProcessLabel.Caption:= inttostr(trunc(i*100/max_))+IntToStr(i-min_)+' èç '+IntToStr(max_-min_)+' îáðàáîòàíî';
Цитата:
Сообщение от phomm Посмотреть сообщение
Ну, по крайней мере, Вы не указали где среда указывает на ошибку, а вроде иных камней я не вижу.
Надо сказать , сама функция проверки на простоту вопросов не вызвала )
Сразу переходжит на end. в проекте

Цитата:
Сообщение от phomm Посмотреть сообщение
Не код, а кошмар (( где Вы его взяли ?
Сорри, надо отконвертирвать было . Надо будет прогу для форума сделать.

Код в следующем сообщении, так как администратор урезал длину сообщения до 5000 символов. А включая коментарии и разметку, код набухает. Прошу сделать, чтобы в коде 3 символа считалось как за один.
hon вне форума Ответить с цитированием
Старый 22.11.2011, 21:49   #5
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
По умолчанию

ЭТО ПРОДОЛЖЕНИЕ ПРЕДЫДУЩЕГО ПОСТА!!!

Код:
unit Prostye_chisla;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls;

{type указан в топике без форматирования из-за превышения на 112
символов.}

var
  Form1: TForm1;

implementation

{$R *.dfm}

CONST LiD=RUSSIAN_CHARSET;
var
  Canceled,CanceledExit,Busy:boolean;


procedure TForm1.Button1Click(Sender: TObject);
var
  f:textfile;
  i,min_,max_:Int64;
  min__,max__:integer;
  crs : TCursor;
  Percent:ShortString;
   function checksimple(i: integer): boolean;
   var j:integer;
   begin
        if i<=1 then
           begin
           result:=false;
           Exit;
           end;
        for j:=2 to i-1 do
            begin
            if i mod j=0 then
               begin
               result:=false;
               Exit;
               end;
            end;
        result:=true;
   end;

   function IsNumberOnly(s:string):boolean;
   var
     i,j:byte;
     res:array of boolean;
   begin
     SetLength(res,Length(s));
     for i:=1 to Length(res) do res[i]:=false;
     //обнуляем массив
     for i:=1 to Length(s) do
         for j:=0 to 9 do
             if s[i] = IntToStr(j) then
                begin
                res[i]:=true;
                end;

     for i:=1 to Length(res) do
         if res[i]=false then
            begin
            result:=false;
            Exit;
            end;
     result:=true;
   end;
//   function FloatToInt
begin
     if IsNumberOnly(min.Text)=false then
        begin
        MessageBoxEx(Form1.Handle, PChar('Разрешены только цифры!'), PChar('Ошибка'), MB_OK+MB_ICONSTOP, LiD);
        min.SetFocus;
        Exit;
        end;
     if NOT IsNumberOnly(max.Text)=false then
        begin
        MessageBoxEx(Form1.Handle, PChar('Разрешены только цифры!'), PChar('Ошибка'), MB_OK+MB_ICONSTOP, LiD);
        max.SetFocus;
        Exit;
        end;
     min_:=StrToInt(min.Text);
     max_:=StrToInt(max.Text);
//     Initialize(min__,max__);
     min__:=min_; max__:=max_;
{}{}{}{}{}     ProgressBar1.Min:=min__;
     ProgressBar1.Max:=max__;
//     Finalize(min__,max__);
     Canceled:=false; CanceledExit:=false; Busy:=true;

     if v_fajl.Text='' then
        begin
        MessageBoxEx(Form1.Handle, PChar('Не записан путь к файлу!'), PChar('Ошибка'), MB_OK+MB_ICONSTOP, LiD);
        Exit;
        end;
     Button1.Enabled:=false;
     ButtonCancel.Enabled:=true;
     Assignfile(f,v_fajl.Text);
     Rewrite(f);
     crs:=Screen.Cursor;
     Screen.Cursor:=crHourgLass;
     i:=min_; ProcessLabel.Caption:='0% 0 из '+IntToStr(max_)+' обработано';
     while i<>max_ do
         begin
         if checksimple(i) then Writeln(f,i);
         ProgressBar1.Position:=i;
         i:=i+1;
         Percent:=FloatToStr(Int( i*100/max_ ))+','+Copy(FloatToStr(Frac( i*100/max_ )),3,1)+'% ';
         if Percent[Length(Percent)-2]=',' then Delete(Percent,Length(percent)-2,1);
         ProcessLabel.Caption:=Percent+IntToStr(i-min_)+' из '+IntToStr(max_-min_)+' обработано';
         Application.ProcessMessages;
         if Canceled then break;
         end;
     Closefile(f);
     Screen.Cursor:=crs;
     if NOT Canceled then MessageBoxEx(Form1.Handle, PChar('Вычисление простых чисел выполнено'), PChar('Готово'), MB_OK+MB_ICONINFORMATION, LiD)
                     else MessageBoxEx(Form1.Handle, PChar('Вычисление простых чисел ПРЕРВАНО'), PChar('Готово'), MB_OK+MB_ICONINFORMATION, LiD);
     Button1.Enabled:=true; ButtonCancel.Enabled:=false; Busy:=false;
     if CanceledExit then Close;
end;

procedure TForm1.ObzorClick(Sender: TObject);
var SD:TSaveDialog;
begin
     SD:=TSaveDialog.Create(nil);
     SD.Filter:='Текстовые файлы|*.txt|Все файлы|*.*';
     SD.Options:=SD.Options+[ofOverwritePrompt];
     if SD.Execute=true then v_fajl.Text:=SD.FileName;
     SD.Free;
end;

procedure TForm1.ButtonCancelClick(Sender: TObject);
begin
   Canceled:=true;
   Button1.Enabled:=true;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if Busy then
      if MessageBoxEx(Form1.Handle, PChar('Прервать вычесление и выйти?'), PChar('Выход'), MB_YESNO+MB_ICONQUESTION, LiD)
         =idYes then begin
                     Canceled:=true;
                     CanceledExit:=true;
                     end
                else Action:=caNone;
end;

end.
Вся программа включая форму и другие файлы проекта прикреплена.
Вложения
Тип файла: rar 7_Простые числа.rar (173.3 Кб, 8 просмотров)
hon вне форума Ответить с цитированием
Старый 22.11.2011, 21:53   #6
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
[CODE]
Ошибка, мне кажется, кроется в фееричной обработке вычислений процентов, там понапихано и строки и переводы из строк и обратно, и удаление символов и ещё кое-что. Советую не мудрить, а единожды вычислить процент в виде дробного числа и уже потом присвоить его с округлением в прогреслейбл, например как-то так:
Код:
ProcessLabel.Caption:= inttostr(trunc(i*100/max_))+IntToStr(i-min_)+' èç '+IntToStr(max_-min_)+' îáðàáîòàíî';
Так первая цифра может быть не 1, а любой, например 5123.
hon вне форума Ответить с цитированием
Старый 22.11.2011, 21:59   #7
hon
Форумчанин
 
Регистрация: 08.06.2011
Сообщений: 693
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Ну, по крайней мере, Вы не указали где среда указывает на ошибку, а вроде иных камней я не вижу.
Надо сказать , сама функция проверки на простоту вопросов не вызвала )
При откладочной работе нашел где стоп:
Код:
     min__:=min_; max__:=max_;
{здесь}     ProgressBar1.Min:=min__;
     ProgressBar1.Max:=max__;
И это когда От=10000, До=11000, что меньше High(integer).
hon вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Invalid Pointer Operation Стелс Компоненты Delphi 1 25.09.2011 21:24
Invalid pointer operation. KoBRaAndrey Общие вопросы Delphi 6 02.06.2010 17:32
Invalid Pointer Operation csander Общие вопросы Delphi 0 21.10.2009 17:44
Invalid Pointer Operation Unconnected Общие вопросы Delphi 3 21.02.2009 20:23
Invalid pointer operation Димарик Общие вопросы Delphi 2 05.11.2007 09:53