VovaN |
Отправлено: 30.05.2005, 10:47 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 72
|
Как определить, что переменная типа AnsiSting равна Null а не пустой строке? |
|
Guest |
Отправлено: 30.05.2005, 11:00 |
|
Не зарегистрирован
|
Так и проверяйте:
CODE |
AnsiString s = NULL;
if( s == NULL ) ...
|
CODE |
Запустите пример и посмотрите что он выдаст в каждом случае:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString s1 = "dsfdsf";
AnsiString s2 = "";
AnsiString s3 = NULL;
if(s1 == "") ShowMessage("s1 == \"\" ");
if(s1 == NULL) ShowMessage("s1 == NULL ");
if(s1 != "") ShowMessage("s1 != \"\" ");
if(s2 == "") ShowMessage("s2 == \"\" ");
if(s2 == NULL) ShowMessage("s2 == NULL ");
if(s2 != "") ShowMessage("s2 != \"\" ");
if(s3 == "") ShowMessage("s3 == \"\" ");
if(s3 == NULL) ShowMessage("s3 == NULL ");
if(s3 != "") ShowMessage("s3 != \"\" ");
}
| |
|
VovaN |
Отправлено: 30.05.2005, 11:07 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 72
|
Я пишу
CODE |
if (previous_str==NULL)
{}
else
{
}
|
При этом watch list показывает, что previous_str:{NULL}
но всегда идет ветвление на else.
Отредактировано VovaN — 30/05/2005, 11:08 |
|
Gedeon |
Отправлено: 30.05.2005, 11:28 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Вот так попробуйте
CODE |
if(str.data()==NULL); |
|
|
olegenty |
Отправлено: 30.05.2005, 11:44 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
а я делаю так:
CODE |
if (str.Trim() == "")
{
...
} else
{
...
}
|
правда, такая проверка более общая: и на пустые строки, и на строки только из переносов кареток, пробелов и табуляции (т.е. — обобщённые пробелы), ну и на NULL, до кучи
|
|
VovaN |
Отправлено: 30.05.2005, 12:46 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 72
|
В том то и проблемма, что надо отличать, где строка Null, а где "".
А все эти методы это не различают.
|
|
Gedeon |
Отправлено: 30.05.2005, 13:37 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Тот способ, который я привел правильно работает, создайте консольное вслное приложение и скопируйте туда следующий код, посмотрите на результат
CODE |
//---------------------------------------------------------------------------
#include <vcl.h>
#include <stdio>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
AnsiString tstNULL, tstNOTNULL;
tstNOTNULL = NULL;
if(tstNULL.data()==NULL)
{
printf("%s\n",tstNULL.data());
printf("AnsiString IS NULL\n");
printf("%s\n",tstNOTNULL.data());
printf("AnsiString IS NOT NULL\n");
}
else{
printf("tstNULL IS NOT NULL\n");
}
system("PAUSE");
return 0;
}
//--------------------------------------------------------------------------- |
Отредактировано Gedeon — 30/05/2005, 13:38
|
|
Gedeon |
Отправлено: 30.05.2005, 14:15 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Я тут еще маленько покопался и вот что получается
AnsiString.data() вернет NULL если строка просто пустая, т.е. если она будет = "" это уже будет NULL, чем собственно она и отличается от c_str(). Т.е. когда Вы пишите
AnsiString tst = NULL; это то же самое, что написать tst = 0; или tst = "0"; соответственно и проверять можно
CODE |
if(tst=="0")
{
printf("IF Work\n");
} |
|
|
** avtoritet |
Отправлено: 30.05.2005, 15:07 |
|
Не зарегистрирован
|
Солидарен с гедеоном.
Я думаю так:
NULL — константа, скрывающая за собой 0;
IsEmpty вернет труе, если str == "";
String str;// тоже что String str ="";
if(str.IsEmpty)
ShowMessage("Empty");
|
|
olegenty |
Отправлено: 30.05.2005, 15:45 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
ну, если что, то писать можно и
CODE |
AnsiString as = (char*)NULL;
|
тут "0" и пахнуть не будет, поскольку лупень BCB просто NULL считает за int
это раз. и, в цикле так делать нельзя — это 2. сто раз обсуждалось на xportal.
найдите n отличий:
CODE |
AnsiString((char*)NULL);
|
разница в том, что в первом случае конструктор вызывается 2 раза: непосредственно для экземпляра правой части присваивания, потом конструктор копирования, потом деструктор для экземпляра правой части, а во втором всего один раз для экземпляра слева, и всё.
поиграл с функцией IsEmpty() — она идиотка. или, нужна ещё одна функция — IsNull(), которой нет.
IsEmpty идиотка, потому что для неё и (char*)NULL, и "" — означает Empty, в то время как я, например, "" — не считаю Empty, а считаю пустой строкой.
|
|
olegenty |
Отправлено: 30.05.2005, 15:54 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
фу, глупость получилась: "Empty" и есть "Пустая". я имел в виду, что для меня (особенно как следствие работы с БД), пустая строка и NULL далеко не эквивалентны. а вот AnsiString наивно полагает, что эквивалентны.
|
|
** avtoritet |
Отправлено: 30.05.2005, 16:16 |
|
Не зарегистрирован
|
Тут рыть можно до посинения!
String str; string str = "";- это эквивалентно? Я думаю да!
Насчет пустой строки и нул полностью с тобой согласен.
Насчет БСБ и НУЛ думаю всеже считает за Variant. Так как:
String str = "0";
if(str == NULL)
ShowMessage("0 — NULL");
А вообще поступать можно всяко, в зависимости от задачи. Хотелось бы знать, а какую задачю хотел решить влад?
|
|
Admin |
Отправлено: 30.05.2005, 17:59 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
Так чем вам не нравиться прямой вариант,
о котором я уже писал (под Guest): ?????????????????
if(s == NULL) ...
все ведь работает в нижеприведенном примере !?
Наверное где то не в том месте стоит else {}
вот такие проблемы и возникают !
CODE |
AnsiString s3 = NULL;
if(s3 == NULL) {
ShowMessage("s3 == NULL ");
}
else {
ShowMessage("s3 != NULL "); // сюда не попадете если NULL
}
|
проверьте этот код — он абсолютно корректо работает
и различает NULL и не NULL и ""
|
|
VovaN |
Отправлено: 30.05.2005, 19:20 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 72
|
Да, я не спорю, что если писать
AnsiString s=Null, то оно конечно работает.
Но вот если писать просто
AnsiString s;
AnsiString s1="";
то отличить нельзя.
Проблемма именно в этом.
|
|
Guest |
Отправлено: 30.05.2005, 21:45 |
|
Не зарегистрирован
|
Так и пишите при инициализации переменной s:
AnsiString s = NULL; вот и будете отличать от ""
|
|
dvv |
Отправлено: 30.05.2005, 23:21 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 43
|
QUOTE (VovaN @ 30/05/2005, 19:20) | Да, я не спорю, что если писать
AnsiString s=Null, то оно конечно работает.
Но вот если писать просто
AnsiString s;
AnsiString s1="";
то отличить нельзя.
Проблемма именно в этом. |
Когда мы пишем: AnsiString s; то s инициализируется в runtime посредствам конструктора AnsiString(), который устанавливает пустую строку.
Когда мы пишем: AnsiString s=""; то s инициализируется во время компиляции так же пустой строкой.
Нельзя отличить пустую строку от точно такой же пустой строки. Оба объекта в памяти занимают 4 байта, у обоих все байты равны '\0' и в памямяти адреса могут находится рядом. Ну кто оличит корейца от корейца?
А вот когда мы пишем AnsiString s=NULL; то s инициализируется во время компиляции значением NULL. Ведь NULL это не строка, NULL это то чего нет. Вот его то и можно отличать от первых двух случаев.
Как отличать — уже описано выше.
Отредактировано dvv — 30/05/2005, 23:34 |
|