Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > вектор, ListBox и Memo


Автор: artsb 27.11.2007, 00:00
Вот кусочек кода:
Код

... // библиотеки

struct gr{
AnsiString name;
AnsiString www;
TStrings *inf;
};
vector<gr> grp;

...

void __fastcall TForm1::Button1Click(TObject *Sender)
{
gr temp;
temp.name=Edit2->Text;
temp.www=Edit1->Text;
temp.inf=Memo1->Lines;
grp.push_back(temp);
ListBox1->AddItem(temp.name,ListBox1);
}

...

void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
int i=ListBox1->ItemIndex;
Label4->Caption=grp[i].www;
Edit2->Text=grp[i].name;
Memo1->Lines=grp[i].inf;
}

...


Здесь при нажатии на кнопку, в вектор добавляется новая запись и в ListBox записывается строка. При щелчке по ListBox'у определяется индекс выбранной строки. По номеру индекса находится номер записи в векторе и данные из него заносятся в поля. Так вот, в Label и Edit заносятся хорошо, а Memo почему-то остаётся пустым. В чём может быть дело?

Автор: JackYF 27.11.2007, 00:32
Цитата(artsb @  27.11.2007,  00:00 Найти цитируемый пост)
Memo1->Lines=grp[i].inf;

Имхо, в указателях:

*Memo1->Lines=*grp[i].inf;

Автор: Fazil6 27.11.2007, 00:42
Код

Memo1->Lines=grp[i].inf;

замени на
Код

Memo1->Lines->Assign(grp[i].inf);


Добавлено через 8 минут и 25 секунд
и здесь аналогично
Код

temp.inf=Memo1->Lines; // заменить на
temp.inf->Assign(Memo1->Lines);

Автор: artsb 27.11.2007, 10:22
JackYF если пишу
*Memo1->Lines=*grp[i].inf; 
вылетает ошибка.


Fazil6 если делаю как ты пишешь, программа запускается, но когда нажимаешь кнопку, выскакивает ошиба. Ругается на эту строку:
temp.inf->Assign(Memo1->Lines);
Если без неё, то никаких изменений нет.

Автор: HappyLife 27.11.2007, 10:52
Код

... // библиотеки
struct gr{
AnsiString name;
AnsiString www;
AnsiString inf;
};
vector<gr> grp;
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
gr temp;
temp.name=Edit2->Text;
temp.www=Edit1->Text;
temp.inf=Memo1->Lines->Text;
grp.push_back(temp);
ListBox1->AddItem(temp.name,ListBox1);
}
...
void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
int i=ListBox1->ItemIndex;
Label4->Caption=grp[i].www;
Edit2->Text=grp[i].name;
Memo1->Lines->Text=grp[i].inf;
}
...

Автор: Fazil6 27.11.2007, 10:56
Цитата(artsb @  27.11.2007,  10:22 Найти цитируемый пост)
Ругается на эту строку:temp.inf->Assign(Memo1->Lines);

вообще-то по уму надо создавать объект для inf

Код

struct gr{
AnsiString name;
AnsiString www;
TStrings *inf;

gr()
{
   inf = new TStringList();
}

~gr()
{
    delete inf;
}

};

Автор: artsb 27.11.2007, 13:29
Спасибо всем. Что-то я ступил. Сохранял в векторе в inf указатель на мемо, но текст в мемо каждый раз изменялся.
Работает код предложенный HappyLife и Fazil6. За что им БОЛЬШОЕ спасибо. 

Скажите теперь, какой из них лучше использовать.

Автор: SenkraD 27.11.2007, 14:00
artsb,  использовать необходимо обе подсказки (более коректнее звучит, исправления)

Автор: artsb 27.11.2007, 16:40
SenkraD но я же не могу одновременно и то и то написать. smile 

Автор: Fazil6 27.11.2007, 16:42
Цитата(artsb @  27.11.2007,  16:40 Найти цитируемый пост)
SenkraD но я же не могу одновременно и то и то написать.

ну так смотря что тебе нужно. Если тебе массив строк в inf нужен, то моё, если просто строкой весь текст, то и второй вариант сойдет

Автор: artsb 27.11.2007, 22:17
Fazil6, тогда твоё.
Всем спасибо. Вопрос решён.

Автор: artsb 29.11.2007, 23:45
Странно! Когда использую способ предложенный Fazil6, при создании первого элемента массива всё нормально, а вот при создании второго вылетает ошибка.
Воспользовался способом HappyLife, всё нормально и работает так как надо.
Кто-нибудь знает с чем это связано. Просто интересно.

Автор: Fazil6 30.11.2007, 10:50
Цитата(artsb @  29.11.2007,  23:45 Найти цитируемый пост)
Кто-нибудь знает с чем это связано. Просто интересно.

 В какой массив? какая ошибка?
ты правда считаешь, что тут кто-то догадается?

Автор: SenkraD 30.11.2007, 11:01
artsb, если ты о первом посте Fazil6 без использования
 его второго поста, то твой креш по причине AV очевиден.

P.S. А вообще, сколько раз говорить, что здесь телепатов нет - откуда
мне (нам) знать как ты используеш подсказки того или иного участника
дискусии, если это можно так назвать

Автор: artsb 30.11.2007, 18:43
Использую эту структуру:
Код

struct gr{
AnsiString name;
AnsiString www;
TStrings *inf;
gr()
{
   inf = new TStringList();
}
~gr()
{
    delete inf;
}
};
vector<gr> grp;
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
gr temp;
temp.name=Edit2->Text;
temp.www=Edit1->Text;
temp.inf=Memo1->Lines;
grp.push_back(temp);
ListBox1->AddItem(temp.name,ListBox1);
}
...
void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
int i=ListBox1->ItemIndex;
Label4->Caption=grp[i].www;
Edit2->Text=grp[i].name;
Memo1->Lines=grp[i].inf;
}
...

И как я писал, при добавлении второго элемента в вектор, вылетает ошибка:


Автор: SenkraD 30.11.2007, 19:58
artsb,  нужно ещё оператор равно и конструктор копирования реализовать:
Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
gr temp;
temp.name=Edit2->Text;
temp.www=Edit1->Text;
temp.inf=Memo1->Lines; // Нужен temp.inf->Assign(Memo1->Lines);
                                        // иначе ты будеш указывать туда куда и Memo1->Lines = изменил текст в Memo1
                                        // и он изменился в векторе + при таком раскладе все в векторе будут указывать на
                                        // одно и тоже место - короче, тебе не это нужно 
grp.push_back(temp); // тут вызывается конструктор копирования для  того, что бы занести temp в вектор
ListBox1->AddItem(temp.name,ListBox1);
}

// temp - временный обьект - после выхода с функи он разрушется ->
//  вызовется деструктор -> всё грохнется, ибо ты в деструкторе сносиш указатель  и ещё не обнуляеш ->
//  елементы вектора и Memo1 указывают на муссор. и при первой попытке обращения к их методам вызовет крах.

// P.S. Знатоки поправьте если я не прав

Автор: artsb 1.12.2007, 16:47
Пробовал так:
temp.inf->Assign(Memo1->Lines);
Но результат тот же.

Автор: SenkraD 2.12.2007, 10:53
artsb, ты в инете смотрел что такое конструкт ор копирования и когда он необходим?
Я специально не писал пример, чтобы ты поискал. Ну раз дело туго, то:
Код

struct gr{
    AnsiString name;
    AnsiString www;
    TStrings *inf;
    gr()
    {
        inf = new TStringList();
    }

    gr(const gr &rhv)
    {
        name = rhv.value;
        www = rhv.www;
        
        inf = new TStringList();
        inf->Assign(rhv->inf);
    }

    ~gr()
    {
        delete inf;
    }
};
vector<gr> grp;
//...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    gr temp;
    temp.name = Edit2->Text;
    temp.www = Edit1->Text;
    temp.inf->Assign(Memo1->Lines);
    grp.push_back(temp);
    ListBox1->AddItem(temp.name, ListBox1);
}
//...
void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
    int i                      =ListBox1->ItemIndex;
    Label4->Caption =grp[i].www;
    Edit2->Text         =grp[i].name;
    Memo1->Lines->Assign(grp[i].inf);
}


1. Вообщем, как-то так (писал с головы без Builder'а под рукой).
2. Чтобы избежать лишних копирований лучше хранить в векторе указатели,
    но тогда нужно будет в конце для всех элементов вектора вызвать delete
3. И почитай о работе с памятью (не помешает)

Автор: artsb 2.12.2007, 16:39
Спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)