Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Непонятки с AnsiString.c_str()

2.9K
26 декабря 2004 года
MARcoDEN
8 / / 16.03.2003
На форме находится поле ввода TEdit. Мне нужно перегнать оттуда текст в char*. Делаю это стандартным способом через функцию класса AnsiString c_str. Но в итоге почему-то пропадает последний символ. Вот фрагмент кода:
[COLOR=green]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char *exp = EditExp->Text.c_str();
ShowMessage(exp);
}
[/COLOR]

К примеру, если введенный текст - "5+6*9", то в сообщении выводится "5+6*". Прогнав этот кусок в отладчике, обнаружил, что потеря последнего символа происходит после деструктора AnsiString. Но какая тут взаимосвязь?

P.S. В атаче лежит скриншот из отладчика.
376
26 декабря 2004 года
Absolut
220 / / 22.11.2002
Делай
--
ShowMessage( EditExp->Text.c_str() );
--
И всё будет ОК. Или копируй содержимое строки а не адрес.
2.9K
26 декабря 2004 года
MARcoDEN
8 / / 16.03.2003
Цитата:
Originally posted by Absolut
Делай
--
ShowMessage( EditExp->Text.c_str() );
--
И всё будет ОК. Или копируй содержимое строки а не адрес.


Да нет, мне важно не сообщение показать (это я сделал для наглядности), а важно получить правильный char*. Объясни, что значит "копируй содержимое строки а не адрес"?

376
26 декабря 2004 года
Absolut
220 / / 22.11.2002
Цитата:
Originally posted by MARcoDEN

Да нет, мне важно не сообщение показать (это я сделал для наглядности), а важно получить правильный char*. Объясни, что значит "копируй содержимое строки а не адрес"?


--
strcpy( exp, EditExp->Text.c_str() );
--
Предварительно выделив необходимое кол-во памяти для exp.
Либо :
--
char exp[max_len]; // с заведомо известной максимальной длиной
// либо
char* exp = new char[EditExp->Text.Length()+1];
// но потом не забывай
delete [] exp;

310
26 декабря 2004 года
fellow
853 / / 17.03.2003
То, что возвращает c_str(), следует немедленно копировать куда-нибудь ещё _целиком_:

int Size = EditExp->GetTextLen();
Size++;
char *Buffer = new char[Size];
EditExp->GetTextBuf(Buffer,Size);
376
26 декабря 2004 года
Absolut
220 / / 22.11.2002
А для того, чтобы получить правильный char* надо вызывать c_str() именно тогда, когда нужно, а не раньше!
2.9K
26 декабря 2004 года
MARcoDEN
8 / / 16.03.2003
Цитата:
Originally posted by Absolut
strcpy( exp, EditExp->Text.c_str() );


А вот этого делать как раз нельзя! Попробуй сам вбить такое в Билдере. Тут же вылетит ошибка!

2.9K
26 декабря 2004 года
MARcoDEN
8 / / 16.03.2003
Цитата:
Originally posted by Absolut
char* exp = new char[EditExp->Text.Length()+1];


Это тоже бред!

2.9K
26 декабря 2004 года
MARcoDEN
8 / / 16.03.2003
Цитата:
Originally posted by fellow
То, что возвращает c_str(), следует немедленно копировать куда-нибудь ещё _целиком_:

int Size = EditExp->GetTextLen();
Size++;
char *Buffer = new char[Size];
EditExp->GetTextBuf(Buffer,Size);


Вот этот вариант работает как надо! Спасибо, fellow!

376
26 декабря 2004 года
Absolut
220 / / 22.11.2002
Цитата:
Originally posted by MARcoDEN

А вот этого делать как раз нельзя! Попробуй сам вбить такое в Билдере. Тут же вылетит ошибка!



Если память НЕ выделить - то конечно ошибка вылетит ;-)

487
26 декабря 2004 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Originally posted by MARcoDEN
На форме находится поле ввода TEdit. Мне нужно перегнать оттуда текст в char*. Делаю это стандартным способом через функцию класса AnsiString c_str. Но в итоге почему-то пропадает последний символ. Вот фрагмент кода:
[COLOR=green]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char *exp = EditExp->Text.c_str();
ShowMessage(exp);
}
[/COLOR]

К примеру, если введенный текст - "5+6*9", то в сообщении выводится "5+6*". Прогнав этот кусок в отладчике, обнаружил, что потеря последнего символа происходит после деструктора AnsiString. Но какая тут взаимосвязь?

P.S. В атаче лежит скриншот из отладчика.



c_str() ВСЕГДА возвращает правильный адрес - всетаки не ламеры-же билдер писали...

Здесь все дело в том, чтобы правильно его использовать - причем даже не сам c_str() а AnsiString.

Вот ты привел код

 
Код:
char *exp = EditExp->Text.c_str();
.

Вот этот самый Text - Это ведь наверняка свойство типа AnsiString (__property)? А что собственно делает данное свойство? 100% возвращает локальную переменную а не reference. А все локальные переменные - короткоживущие. И поэтому тот код который ты привел использовать и нельзя - описанная тобой проблема - как раз результат этого.

Так что либо:
 
Код:
ShowMessage(EditExp->Text.c_str());


либо:
 
Код:
AnsiString Temp=EditExp->Text;
char *exp=Temp.c_str();
ShowMessage(exp);



Вот это:

 
Код:
int Size = EditExp->GetTextLen();
Size++;
char *Buffer = new char[Size];
EditExp->GetTextBuf(Buffer,Size);


Абсолютно тоже самое что и AnsiString Temp=EditExp->Text; только использовать такую конструкцию стоит только в исключительных случаях - а в простых - только код громоздить будешь - а толку - 0;
246
27 декабря 2004 года
GIZMO
1.8K / / 30.07.2004
int Size = EditExp->GetTextLen();
Size++;
char *Buffer = new char[Size];
EditExp->GetTextBuf(Buffer,Size);
Цитата:
Originally posted by MARcoDEN

Вот этот вариант работает как надо! Спасибо, fellow!



char* exp = new char[EditExp->Text.Length()+1];
strcpy( exp, EditExp->Text.c_str());
...
delete [] exp;

Цитата:
Originally posted by MARcoDEN

Это тоже бред!
...
А вот этого делать как раз нельзя! Попробуй сам вбить такое в Билдере. Тут же вылетит ошибка!



Это как в анекдоте, где бабушка говорит милиционеру:
- "Иду, смотрю - сношаются!";
- "Пригляделась, е...".

376
27 декабря 2004 года
Absolut
220 / / 22.11.2002
Хороший анекдот :D В тему
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог