Помощь - Поиск - Пользователи - Календарь
Полная версия: Проблема с динамическими массивами...
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Делфи
Шушпан
Помогите пожалуйста
Я пишу процедуру, которая осуществляет добавление элемента в массив при нажатии кнопки. Но при проверке работы выдается ошибка... в чем дело, понять не могу. Не подкажете?
Код
type words=array of string;

procedure add_to_array(var base:words; rus:string);
var k,i:integer;
   tmp:words;
begin
i:=length(base);
tmp:=nil;
setlength(tmp,i+1);
for k:=1 to i do
       begin
       tmp[k]:=base[k];
       end;
tmp[i+1]:=rus;
base:=nil;
i:=i+1;
setlength(base,i);
base:=copy(tmp,0,i);
end;

procedure TForm1.baseframeaddbuttonClick(Sender: TObject);
var i,k:integer;
   str,rus:string;
   base:words;
begin
rus:=baseframe.rusword.Text;
i:=length(base);
add_to_array(base,rus);
end;

plz
Martyr
Хотя бы вот:
Код
tmp[i+1]:=rus;

но
Код
setlength(tmp,i+1);

т. е. индекс последнего элемента будет i, а не i + 1

И вообще, все как-то усложнено. Можно и попроще:

Код

procedure add_to_array(var base: words; const rus: string);
var
  i: integer;
begin
  i := length(base);
  setlength(base, i + 1);
  base[i] := rus;
end;
Шушпан
Попробовал, но теперь вообще ничего не происходит... при попытке вывести любого элемента этого массива в... TEdit или TLabel
Блин
-Volvo-
Шушпан
Можно привести пример попытки вывода элемента в TEdit? У меня процедура, предложенная Martyr отработала без всяких проблем...
Martyr
Шушпан, подозреваю, у тебя возникают проблемы из-за того, что base (та, что внутри baseframeaddbuttonClick) - не глобальная переменная...
Шушпан
Хм...
Две переделанные процедуры теперь выглядят так:
Код

var base:words;

procedure add_to_array(var base:words; rus:string);
var i:integer;
begin
 i := length(base);
 i:=i+1;
 setlength(base, i);
 base[i] := rus;
end;

procedure TForm1.baseframeaddbuttonClick(Sender: TObject; var base:words);
var i,k:integer;
   str,rus:string;
begin
rus:=baseframe.rusword.Text;
add_to_array(base,rus);
i:=length(base);
{вывод массива в TEdit}
for k:=1 to i do
       begin
       str:=str+', '+base[k];
       end;
baseframe.edit3.text:=str;
end;
volvo
Ну я бы все-таки вот так сделал:
Код
procedure TForm1.baseframeaddbuttonClick(Sender: TObject; var base:words);
var i,k:integer;
  str,rus:string;
begin
 rus:=baseframe.rusword.Text;
 add_to_array(base,rus);
 i:=length(base);
 {вывод массива в TEdit}
 str := ''; // это желательно
 for k:=0 to Pred(i) do // Внимание !!! элементы начинаются с 0-го
   begin
     str:=str+', '+base[k];
   end;
 baseframe.edit3.text:=str;
end;
Шушпан
Спасибо, теперь буду разбираться во всем остальном smile.gif
Премного благодарен!!!

ДОбавление:
Упс, еще одна проблема. Как можно применить функцию length к многомерным динамическим массивам ?
Я пытаюсь так:
Код

procedure add_to_arr(var base:words; const rus,eng:string);
var i:integer;
begin
i:=length(base[cols]);    {так}
i:=i+1;
setlength(base, cols, i);
base[0,pred(i)]:=rus;
base[1,pred(i)]:=eng;
end;

При проверке работы программы компилятор выдает ошибку "Project raised exception class EAcessViolation with message......." и т.д. Как же использовать эту функуцию... Читал FAQ - там не нашел.
Подскажите кто-нибудь, пожалуйста.
volvo
Стоп, стоп... Как Base описан, можно узнать?
Если это тот же тип Words, то так и не должно работать...
Шушпан
Нет, то уже другой тип : words= array of array of string;
volvo
Ну если
Цитата(Шушпан)
words= array of array of string;

то делаем так:
Код
procedure add_to_arr(var base:words; const rus,eng:string);
var i: integer;
begin
 i:=length(base[cols]);    {так}
 i:=i+1;
 setlength(base[cols], i); // Вот это !!!
 base[0][pred(i)]:=rus;
 base[1][pred(i)]:=eng;
end;


Только что проверил - все работает...
Шушпан
Не работает :D
Может все процедуры тебе показать ? Посмотри пожалуйста

Код

type
   words=array of array of string;
...
const cols=2;
var base:words;
...

procedure add_to_arr(var base:words; const rus,eng:string);
var i: integer;
begin

i:=length(base[cols]);    {компилятор выделяет эту строку красным цветом}

i:=i+1;
setlength(base[cols], i); // Âîò ýòî !!!
base[0][pred(i)]:=rus;
base[1][pred(i)]:=eng;
end;

procedure refreshbaseview(base:words; var str:string);
var i,k:integer;
begin
str:='';
i:=length(base[cols]);
for k:=0 to pred(i) do
if k= 0 then str:= base[0,k] + ' - ' + base[1,k] +';' +#13
       else str:= str + base[0,k] + ' - ' + base[1,k] + ';' +#13;
end;

procedure TForm1.baseframeaddbuttonClick(Sender: TObject);
var str:string;
begin
add_to_arr(base,baseframe.rusword.Text,baseframe.engword.text);
refreshbaseview(base, str);
baseframe.baseview.Caption:=str;
baseframeClearbuttonClick(sender);
end;

volvo
Цитата(Шушпан @ 24.02.05 15:32)
Не работает

А к тому моменту, когда программа попадает на эту строку, длина base уже установлена? (как минимум она должна быть уже равна 3...) То есть где-то при инициализации неплохо было бы добавить
Код
setlength(base, 3);

и уже потом продолжать... А сейчас что происходит? все действия должны производиться со второй строкой, но Base вообще не инициализирован...

P.S. Кстати, а почему Cols = 2 все время?
Шушпан
А это так надо smile.gif
Я пишу программу-переводчик с русского на английский, первый столбец в строке - русское слово, а второе - соответствующее ему английское...
Вставил
Код

setlength(base,3)


при запуске программы, ошибка все равно осталась, правда теперь эта строка не выделяется...
А разве не будет length(неинициализированного массива)=0 ?
volvo
Ха-ха-ха... Я только что увидел:

У тебя Base имеет вот такую структуру:
Цитата
base[0]: [string1][string2][string3]...[stringN]
base[1]: [string1][string2][string3]...[stringN]

Тогда и изменять длину их надо вместе...
Код
procedure add_to_arr(var base:words; const rus,eng:string);
var i: integer;
begin

i:=length(base[0]);

i:=i+1;
setlength(base[0], i); // увеличиваем длину первого массива
setlength(base[1], i); // увеличиваем длину второго массива
base[0][pred(i)]:=rus; // и работаем с ними
base[1][pred(i)]:=eng;
end;


Или можно сделать по-другому (но тогда многое придется переделывать):
Код
type strRec = record
 rus, eng: string;
end;
var base: array of strRec;
Шушпан
Спасибо, у меня только что та же мысль родилась smile.gif
А последний предложенный вариант очень мил smile.gif буду пробовать smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.