Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Динамический массив типа Record [D6, WinXP]


Страницы:   1 2 3

Pavelkq ©   (2004-07-01 13:01:00) 

Здравствуйте! Есть задача создать массив кривой структуры:
1. Первое поле содержит всего одно число типа longint.
2.Второе поле это динамический массив такого типа:
2.1. Тип string
2.2. Тип longint
2.3. Тип динамический массив типа string
2.4. Тип динамический массив типа LingInt
 Делаю все, как по часам:

// Создание структуры индексной таблицы (2)
       Type
         TIndex=record
           Lema : string[50];// Пункт 2.1.
           ColLem: LongInt;  // Пункт 2.2.
           Word : array of string[50];// Пункт 2.3.
           Index : array of LongInt;  // Пункт 2.4.
         end;
// Создание массива индекса с полем для пункта 1.
       Type TBase=Record
               Sum:LongInt; // Вот он, пункт 1.
               SIndex:array of TIndex;// Пункт 2 целиком.
          end;
// Назначаем переменную Base вышеуказанного типа.
       var Base:TBase;

 Все компилируется отлично!
Далее начинаю работать с этой таблицей.
Base.Sum:=KakoyToInteger;
SetLength(Base.SIndex,Base.Sum);
...
WordI:=0;// Тип Integer
...
WordI:=WordI+1;
SetLength(Base.SIndex[N].Word,WordI);
SetLength(Base.SIndex[N].Index,WordI);
Base.SIndex[LemI].Word[N]:=Words;
Base.SIndex[LemI].Index[N]:=Int;
...

И вот при WordI=4 на выполнении SetLength(Base.SIndex[N].Index,WordI);вылетает непонятная ошибка и код в CPU.
Может быть реализовать эту структуру в другом типе. Например в баз данных?


Sandman25   (2004-07-01 15:20:00) [21]

[23] Pavelkq   (01.07.04 15:19)

>Включил Range checking и точно по Range checking error вылетел.

И что, до сих пор неясно, как исправить?


Pavelkq   (2004-07-01 15:19:00) [22]

[21] Включил Range checking и точно по Range checking error вылетел.
[22] Вверху в типах явно указано Index : array of LongInt;  // его адрес


R   (2004-07-01 15:05:00) [23]

Пример не рабочий хотя полный,
надо было упростить в один обработчик
Base.SIndex[LemI].Index-это что за тип?


Sandman25   (2004-07-01 14:58:00) [24]

[19] Pavelkq   (01.07.04 14:49)

Включите Range checking на Project-Options-Compiler


DieHard   (2004-07-01 14:55:00) [25]

По идее, падать должно на следующей строчке:
      Base.SIndex[LemI].Word[ WordI]:=Indexes[i1].Word;
      Base.SIndex[LemI].Index[ WordI]:=Indexes[i1].Index;


Pavelkq   (2004-07-01 14:49:00) [26]

[9] Да, есть недочеты. Но не в этом суть проблемы. Почему
SetLength(Base.SIndex[LemI].Word,WordI);проходит, а SetLength(Base.SIndex[LemI].Index,WordI);умирает?
Я, кстати, пробовал сделать тип для Index:String, а дальше поюзать IntToStr. Тогда WirdI доростала до 5.


Тимохов   (2004-07-01 14:47:00) [27]


> Pavelkq   (01.07.04 14:19) [15]

это значит адрес возникновения ошибки.
место ошибки можно найти search\find error.
надо скомпилиться.


Sandman25   (2004-07-01 14:43:00) [28]

[9]


Pavelkq   (2004-07-01 14:42:00) [29]

For LemI:=0 to Base.Sum - 1 doне помогло. Я же говорю, ошибка возникает при LemI=0 и WordI=4.


Pavelkq   (2004-07-01 14:19:00) [30]

Может и для Пушкина, но я его на форуме не встречал. Может кто разъяснит, что это значит?


romeo   (2004-07-01 14:18:00) [31]

SetLength(Base.SIndex,Base.Sum);// Оно же равно количеству строк таблицы
For LemI:=0 to Base.Sum - 1do


Pavelkq   (2004-07-01 14:17:00) [32]

R, я хотел бы создать клас, но что это и с чем его едят? Ничего более простого, чем я сделал, представить не могу:-(
 Мне нужно будет эту всю кучу сохранять в файл. Позже читать и сравнивать... Как лучше сделать? Может БД поюзать?


Digitman   (2004-07-01 14:14:00) [33]


> 'access violation at 0x00401c79


вот эта информация 0x00401c79, она для Пушкина, конечно же, не для тебя


Pavelkq   (2004-07-01 14:13:00) [34]

Продолжение:
// Моя вставка
begin
 FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
 with StartUpInfo do
 begin
   cb := SizeOf(TStartUpInfo);
   dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
   wShowWindow := SW_SHOWNORMAL;
 end;
 Rlst := CreateProcess(nil,
 'rr.res',
 nil,
 nil,
 false,
 NORMAL_PRIORITY_CLASS,
 nil,
 nil,
 StartUpInfo,
 ProcessInfo);
rc:=LoadMcr(PChar(dir));
 if Rlst then
 with ProcessInfo do begin
   WaitForInputIdle(hProcess, INFINITE); // ждем завершения инициализации
   WaitforSingleObject(ProcessInfo.hProcess, INFINITE); // ждем завершения процесса
   GetExitCodeProcess(ProcessInfo.hProcess, ExitCode); // получаем код завершения
   CloseHandle(hThread); // закрываем дескриптор процесса
   CloseHandle(hProcess); // закрываем дескриптор потока
 end
else Error := GetLastError;
end;
// конец моей вставки

// rc:=LoadMcr(PChar(dir));
if rc<=0 then
begin
ShowMessage('Ошибка загрузки словаря. Код '+IntToStr(rc))
end
else
begin
say('Словарь загружен');
end;
Form1.ProgressBar1.Position:=0;
for i1:=1 to i2 do
// Программа от Димы
      begin
      Form1.ProgressBar1.Position:=i1;
      s:=Indexes[i1].Word;
      count:=FindWID(PChar(s),@Uid);
        if count>0 then
          begin
          rc:=GetBid(uid.ids[0].lnk,uid.ids[0].en,false,false,@WData);
            if rc>=0 then
                begin
                strcopy(cstr,CTS(WData.inlex[0].cid));
                strcopy(vstr,VTS(WData.inlex[0].cid,WData.inlex[0].vid));
                s1:='';
                s1:=StrPas(WData.inlex[0].anword);
                Indexes[i1].Lema:=s1;
                Indexes[i1].Index:=i1;
                end;
          end;
      end;
// Конец программы от Димы
end;

Procedure SubIndex();
var LemI,WordI:integer;
   Fdata: TStringList;
   Temp:String;
Begin
  FData:=TStringList.Create;
For i1:=1 to i2 do
   begin                          //************************
   Fdata.Sorted := true;          // Сортировка лем и
   Fdata.Duplicates := dupIgnore; // удаление дубликатов
   FData.Add(Indexes[i1].Lema);   //************************
   end;

{Temp:='';
For i1:=0 to Fdata.Count-1 do
   begin
   Temp:=Temp+FData.Strings[i1]+' ';
   end;
ShowMessage(Temp);}

Base.Sum:=Fdata.Count-1;         // Количество уникальных лем
SetLength(Base.SIndex,Base.Sum);// Оно же равно количеству строк таблицы
For LemI:=0 to Base.Sum do
 begin
 Base.SIndex[LemI].Lema:=FData.Strings[LemI];
 Temp:=FData.Strings[LemI];
 WordI:=0;
 for i1:=1 to i2 do
    begin
    if Base.SIndex[LemI].Lema=Indexes[i1].Lema then
       begin
       WordI:=WordI+1;
       SetLength(Base.SIndex[LemI].Word,WordI);
       SetLength(Base.SIndex[LemI].Index,WordI);
       Base.SIndex[LemI].Word[WordI]:=Indexes[i1].Word;
       Base.SIndex[LemI].Index[WordI]:=Indexes[i1].Index;
       end;
    end;
 end;

end;

Procedure save();
var F : file of TempIndex;
Begin
Form1.ProgressBar1.Position:=0;
AssignFile(F, path+'\index111.dat');
Rewrite(F);
Indexes[0].Index:=i2;
write (F,Indexes[0]);
for i1:=1 to i2 do
        begin
        Write (F, Indexes[i1]);
        Form1.ProgressBar1.Position:=i1;
        end;
CloseFile(F);
End;

procedure TForm1.Button1Click(Sender: TObject);
const
 wdSaveChanges = $FFFFFFFF;
var
   WordApp: OLEVariant;
   Document: OLEVariant;
   SaveChanges: OleVariant;
   AWordDoc: String;
begin
AWordDoc:='';
OpenDialog1.Execute;
AWordDoc:=OpenDialog1.FileName;
if AWordDoc='' then exit;
ProgressBar1.Visible:=true;
     try
     WordApp := CreateOleObject('Word.Application');
     except
     // Error....
     Exit;
     end;
 try
 Document:=WordApp.Documents.Open(AWordDoc);
      say('Чтение файла...');
      Reading (Document);
  SaveChanges := wdSaveChanges;
  WordApp.Quit(SaveChanges, EmptyParam, EmptyParam);

      say('Лематизация');
      Lema();

      say('Создание индекса');
      SubIndex();

      say('Сохранение результатов');
      //Save ();

      say('Готово!');
 finally
 end;
ProgressBar1.Visible:=False;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var result:Integer;
begin
result:=MessageBox(0,'Удалить индексный файл index.dat?','Завершение программы',MB_YESNOCANCEL);
if result=2 then Action := caNone;
if result=6 then DeleteFile(path+'\index111.dat');
end;

end.


Pavelkq   (2004-07-01 14:12:00) [35]

Только не смейтись, я в Дельфях всего месяц:

unit Word3_;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, FileCtrl, ExtCtrls, ComObj, ComCtrls, SndKey32,
 ActnList, WordItemCounter;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   ProgressBar1: TProgressBar;
   Button2: TButton;
   OpenDialog1: TOpenDialog;
   Label1: TLabel;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   procedure FormActivate(Sender: TObject);
   procedure Button3Click(Sender: TObject);
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

// * * * CONST * * * //
const  MAX_WORD_LEN=32; //максимальная длина входного слова
const  MAX_PARA_COUNT=200; //максимальное количество слов в парадигме

// * * * (1.0) Структура определяющая одно слово и его грамматические характеристики   * * *  //
     type TWstr=record
       anword: array[0..MAX_WORD_LEN-1] of char; //словоформа , для совместимости с С++ используется PChar
       cid:byte;     //постоянная грамматическая характеристика
       vid:byte;    //переменная грамматическая характеристика
       virt:char;  //потенциальность словоформы обозначается знаком ~
       para:byte; //внутренняя системная переменная - явно не используется
       end;

// * * * (1.1) Общая структура используемая для добавления или считывания парадигмы или слова * * *//
     type TWs=record
       inlex:array[0..MAX_PARA_COUNT-1] of TWstr;
       count:integer;  //количество
       end;
     pTWs=^TWs; //pointer

// * * * (2.0) Cтруктура определяющая идентификатор UIN 1-го слова * * *//
     type Tid=record
       lnk:longword; //Уникальный идентификатор леммы (максимально 20 бит)
       en:byte;    // Идентификатор окончания (8 бит) Лемма всегда имеет ed:=0
       end;

// * * * (2.1) Общая структура идентификаторов * * *//
     type Tids=record
       ids:array[0..MAX_PARA_COUNT-1] of Tid;
       count:integer;
       end;
       pTids=^Tids; //pointer
       pInt=^integer;

//Массив переменных типа TMember, который мы будем
//использовать для хранения нашего индекса
    type TempIndex=record
       Word : string[50];
       Lema : string[50];
       Index : Integer;
    end;
    var  Indexes : array of TempIndex;
    i1,i2: longword;
    Path: string;
 {
//***********************************************************
// Создание структуры индексной таблицы                   //*
       Type                                              //*
         TIndex=record                                   //*
           Lema : string[50];// лема                     //*
           ColLem: LongInt;  // количество одинаковых лем /*
           Word : array of string[50];// само слово      //*
           Index : array of LongInt;  // его адрес       //*
         end;                                            //*
// Создание массива индекса с полем для количества слов   //*
       Type TBase=Record                                 //*
               Sum:LongInt; // общее кол. слов в файле   //*
               SIndex:array of TIndex;// строки таблицы  //*
          end;                                           //*
// Назначаем грандиозной таблицей переменную Base         //*
       var Base:TBase;                                   //*
//***********************************************************
}
var
 Form1: TForm1;
 function InitMcr: Integer; stdcall; external 'MCR.DLL' name 'InitMcr';
 function LoadMcr(const path:PChar): Integer; stdcall; external 'MCR.DLL' name 'LoadMcr';
 function SaveMcr(const path:PChar): Integer; stdcall; external 'MCR.DLL' name 'SaveMcr';
 function FindWID(const s:PChar; p:pTids): Integer; stdcall; external 'MCR.DLL' name 'FindWID';
 function GetBId(const lnk:integer; en:byte;gh_only,all:boolean;p:pTWs): Integer; stdcall; external 'MCR.DLL' name 'GetBid';
 function FreeSpace(a1,a2,a3:pInt): Integer; stdcall; external 'MCR.DLL' name 'FreeSpace';
 function RODict: boolean; stdcall; external 'MCR.DLL' name 'ReadOnlyDict';
 function GetVer: PChar; stdcall; external 'MCR.DLL' name 'Ver';
 function AddPara(outdata: pTWs): integer; stdcall; external 'MCR.DLL' name 'AddParadigma';
 function CTS(const constid:byte):PChar; stdcall; external 'MCR.DLL' name 'ConstIdToStr';
 function VTS(const constid,varid:byte):PChar; stdcall; external 'MCR.DLL' name 'VarIdToStr';

implementation

uses Unit2;
{$R *.dfm}
{ 1. Change MS Word properties via OLE }

procedure say(s:string);
begin
Form1.Memo1.Lines.Add(s);
end;

procedure close1(); external 'C:\BIBLIO\word+lema6\rr.dll' name 'close';

procedure TForm1.Button2Click(Sender: TObject);
begin
Form2.StringGrid1.Cells[0,0]:='Лема';
Form2.StringGrid1.Cells[1,0]:='Слово';
Form2.StringGrid1.Cells[2,0]:='Номер';
Form1.Visible:=False;
Form2.Visible:=True;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
Memo1.Clear;
path:=GetCurrentDir;
end;

procedure Reading (Document:OLEVariant);
var t1,t2,Temp:string;
TSL: TStringList;
begin
TSL:=TStringList.Create;
Temp:=Document.range;//Копирование всего файла в Temp
say (DateTimeToStr(Now));

   TSL.Text:=WordItem(Temp);//Процедура разбивки
   i2:=TSL.Count; SetLength(Indexes,i2);

Form1.ProgressBar1.Max:=i2;
Form1.ProgressBar1.Position:=0;
       for i1:=1 to i2 do
       begin
       Indexes[i1].Word:=TSL[i1-1];
       Temp:=TSL[i1-1];
       Form1.ProgressBar1.Position:=i1;
       end;
say (DateTimeToStr(Now));
end;

procedure Lema ();
var
         Te:String;
         rc:integer;
         dir:string;
         s,s1:string;
         count,i:integer;
         Uid :Tids;
         WData:TWs;
         cstr,vstr:array[byte] of char;
         h: HWND;
         cl:Boolean;
 Rlst: LongBool;
 StartUpInfo: TStartUpInfo;
 ProcessInfo: TProcessInformation;
 Error: integer;
 ExitCode: Cardinal;
begin
//Hint: правильно укажите путь к файлу
dir:=path+'\zal.mcr';
InitMcr;

Продолжение следует...


Sandman25   (2004-07-01 14:12:00) [36]

[8] romeo   (01.07.04 14:08)

Точнее, автор "забыл" что динамические массивы индексируются, начиная с 0


romeo   (2004-07-01 14:08:00) [37]


> И вот при WordI=4 на выполнении SetLength(Base.SIndex[N].Index,WordI);
> вылетает непонятная ошибка

Видимо у тебя нет члена массива Base.SIndex[N].Index с индексом 'N'


Sandman25   (2004-07-01 13:56:00) [38]

Это потому что KakoyToInteger=4.


R   (2004-07-01 13:55:00) [39]

Покажи рабочий  код без вяких ....

Пример в обработчике кнопки


Pavelkq   (2004-07-01 13:53:00) [40]

Ну... она просто непонятная. Вот:
Project Project1.exe faulted with message: 'access violation at 0x00401c79: write of address 0x00000001'. Process Stoped. Use Step or Run to continue.
 ... и еще окошко CPU.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо