Форум: "Основная";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
Внизпроверить на тип Найти похожие ветки
← →
Bobby Digital © (2004-11-24 05:02) [0]можно ли как то проверить тип данных введных, например в Edit не используя try ... exсept
← →
YurikGL © (2004-11-24 07:10) [1]TryStrToBool()
TryStrToFloat()
TryStrToInt()
← →
ASoft (2004-11-24 07:37) [2]>Bobby Digital
Если тебе нужно вводить в Edit только цифры или цифры ч/з запятую, то в KeyPress Edit"а можно сразу установить проверку ввода с клавы:)
← →
Reindeer Moss Eater © (2004-11-24 10:28) [3]Тип данных введенных в едит можно не проверять.
Это всегда анси строка.
← →
Rutven © (2004-11-24 10:37) [4]
> Тип данных введенных в едит можно не проверять.
> Это всегда анси строка.
Браво. :)
← →
Sandman25 © (2004-11-24 10:44) [5]Если подходить строго, у введенных в едит данных тип PChar.
← →
ASoft (2004-11-24 10:47) [6]>Тип данных введенных в едит можно не проверять.
Сам когда-то пытался проверять при выходе из Edit, что там: число или текст, использовал ф. Val(). Но потом, просто в KeyPress не разрешал вводить буквы или цифры (в зависимости от нужд). Может Автор вопроса это имел ввиду?
← →
ASoft (2004-11-24 10:49) [7]> Может Автор вопроса это имел ввиду? [6]
Кстати, где он, автор?
← →
passlight © (2004-11-24 10:49) [8]А если Copy/Paste? Будет ли работать проверка в таком случае?
← →
ASoft (2004-11-24 10:53) [9]>А если Copy/Paste? Будет ли работать проверка в таком случае?[8]
Хороший вопрос...
← →
ASoft (2004-11-24 11:07) [10]Опять Val()...
перехват клавиш Shift-Ins, Ctrl-C...
навесить на Edit свой Popup...
Как-то не очень...
Кто лучше?
← →
begin...end © (2004-11-24 14:20) [11]
> [10] ASoft (24.11.04 11:07)
> перехват клавиш Shift-Ins, Ctrl-C...
> Как-то не очень...
> Кто лучше?
Обработчик TEdit.OnChange.
← →
Ega23 © (2004-11-24 14:28) [12]Самое лучшее - в обработчике OnButtonOKClick :
procedure TFProfs.btnOkClick(Sender: TObject);
var
ss:String;
ProfID:Integer;
begin
if not CheckControlValues then Exit;
NewDataString:=MakeHistDetStr(nil,eProfNam.Text+";"+eProfLab.Text+";"+
RQ1.FieldByName("WCfgNam").AsString+";"+cbIsActual.Text,
"Название: ;Сокр.: ;АРМ: ;Используется: ","V");
............
ModalResult:=True;
end;
function TFProfs.CheckControlValues: Boolean;
var
ss:string;
Code:Integer;
begin
ss:=eProfNam.Text;
if not CheckOnQuotes(ss,Code) then
begin
if eProfNam.CanFocus then eProfNam.SetFocus;
// PassMessage(Handle,"Символ "+eProfNam.Text[Code]+" является зарезервированым "+CRLF+
// " и не может быть использован",PasMess.capWarning,0);
Exit;
end;
eProfNam.Text:=ss;
ss:=eProfLab.Text;
if not CheckOnQuotes(ss,Code) then
begin
if eProfLab.CanFocus then eProfLab.SetFocus;
// PassMessage(Handle,"Символ "+eProfLab.Text[Code]+" является зарезервированым "+CRLF+
// " и не может быть использован",PasMess.capWarning,0);
Exit;
end;
eProfLab.Text:=ss;
if eProfNam.Text="" then
begin
PassMessage(Handle,PasMess.wrnNamAbs,PasMess.capWarning,0);
eProfNam.SetFocus;
Result:=False;
Exit;
end;
if eProfLab.Text="" then
begin
PassMessage(Handle,PasMess.wrnLabAbs,PasMess.capWarning,0);
eProfLab.SetFocus;
Result:=False;
Exit;
end;
if Mode=0 then
begin
ss:="select ProfNam from Profs where ProfNam=" + ValX(eProfNam.Text);
QuOpen(DMpas.RQTemp,ss);
if not DMpas.RQTemp.IsEmpty then
begin
DMpas.RQTemp.Close;
PassMessage(Handle,PasMess.wrnNamExist,PasMess.capWarning,0);
eProfNam.SetFocus;
Result:=False;
Exit;
end;
ss:="select ProfLab from profs where proflab=" + ValX(eProfLab.Text);
QuOpen(DMpas.RQTemp,ss);
if not DMpas.RQTemp.IsEmpty then
begin
DMpas.RQTemp.Close;
PassMessage(Handle,PasMess.wrnLabExist,PasMess.capWarning,0);
eProfLab.SetFocus;
Result:=False;
Exit;
end;
end;
Result:=True;
end;
← →
Bobby Digital © (2004-11-24 23:58) [13]мне нужно было различать - Integer Float String
я написал простю функцию ... которая проверяет каждый символ в строке, например, если все цифры то Интежер .. и тд.
← →
Юрий Зотов © (2004-11-25 00:20) [14]type
TDataType = (dtInteger, dtFloat, dtString);
function GetDataType(S: string): TDataType;
var
I: integer;
F: double absolute I;
begin
if TryStrToInt(S, I) then
Result := dtInteger
else
if TryStrToFloat(S, F) then
Result := dtFloat
else
Result := dtString
end;
← →
GuAV © (2004-11-25 01:25) [15]Юрий Зотов © (25.11.04 0:20) [14]
А не кажется ли Вам что
Юрий Зотов © (25.11.04 0:20) [14]
F: double absolute I;
- плохой код, учитывая что ЫшяуЩа(Штеупук) = 4 ,а SizeOf(Double) = 8. Вы можете конечно доказать, что ничего не перезаписываете но всё же правильнее было бы I: integer absoulte F;. А ещё правильнее IMHO не экономить одно слово в стеке и объявиь F и I отдельно.
← →
GuAV © (2004-11-25 01:25) [16]GuAV © (25.11.04 1:25) [15]
ЫшяуЩа(Штеупук) = 4
SizeOf(Integer) = 4
← →
GuAV © (2004-11-25 01:36) [17]Попробовал. GetDataType("7,8"); - AV. Прикольно.
← →
Bobby Digital © (2004-11-25 01:52) [18]А что зн. выражение F: double absolute I;
← →
GuAV © (2004-11-25 01:58) [19]Bobby Digital © (25.11.04 1:52) [18]
А что зн. выражение F: double absolute I;
То что переменная F инеющая тип double находится о тому же адресу что и переменная I. В данном случае такая конструкция ошшибочна, поскольку размер переменной F больше чем размер переменной I и поэтому чтение/запись переменной F может привести к чтению/записи посторонних данных.
Не следует пользоваться absolute без нужды.
Здесь можно написатьvar
I: integer;
F: double;
Подробнее absolute+F1
← →
ASoft (2004-11-25 07:04) [20]GetDataType() это действительно здорово, что еще раз доказывает: "создавайте свои типы". Но как быть с проверкой при выходе из MaskEdit, ведь событие (ошибка) EDBEditError срабатывает раньше, чем проверочная функция? Написать свой обработчик ошибок?
← →
Leonid Troyanovsky (2004-11-25 09:56) [21]
> ASoft (25.11.04 07:04) [20]
> GetDataType() это действительно здорово, что еще раз доказывает:
> "создавайте свои типы". Но как быть с проверкой при выходе
> из MaskEdit, ведь событие (ошибка) EDBEditError срабатывает
> раньше, чем проверочная функция? Написать свой обработчик
> ошибок?
Например
http://groups.google.com/groups?selm=41931491%40f1003.n5080.z2.fidonet.ftn
--
С уважением, LVT.
← →
ASoft (2004-11-25 10:56) [22]>>Leonid Troyanovsky[21]
Спасибо за инфу, собственно, то, что я и предполагал:
"on E: EDBEditError do
raise Exception.Create("My exception"); // do something" -
свой перехват Exception.
← →
Юрий Зотов © (2004-11-25 14:42) [23]> GuAV © (25.11.04 01:25) [15]
> А не кажется ли Вам что
Мне кажется, что компилятор все же отведет 8 байт, а не 4.
> Вы можете конечно доказать, что ничего не перезаписываете, но
> всё же правильнее было бы I: integer absoulte F.
Если первое утверждение верно, то неверно второе.
> А ещё правильнее IMHO не экономить одно слово в стеке и
> объявиь F и I отдельно.
ЧЕМ правильнее?
← →
jack128 © (2004-11-25 14:48) [24]Юрий Зотов © (25.11.04 14:42) [23]
ЧЕМ правильнее?
вот этим, видимо
>GuAV © (25.11.04 1:36) [17][Ответить]
> Попробовал. GetDataType("7,8"); - AV. Прикольно.
;-)
← →
GuAV © (2004-11-25 14:50) [25]Юрий Зотов © (25.11.04 14:42) [23]
Если первое утверждение верно, то неверно второе.
Я уже проверил. [17] - AV.
Компилятор однозначно отведёт 4 байта. Первое утверждение верно.
Я думал что второе утверждение верно, исходя из того что Вы проверили код передтем как запостить. Компилятор выделил бы 4 байта но недостающие 4 байта не содержали бы используемых данных. Да, я ошибся второе утверждение не верно.
← →
GuAV © (2004-11-25 14:55) [26]Юрий Зотов © (25.11.04 14:42) [23]
ЧЕМ правильнее?
тем что если при незначительной выгоде от absolute (4 байта в стеке по памяти, по скорости 0 или почти 0) так легко сделать ошибку. Что Вы и продемонстрировали.
также тем что код становится менее понятным, что продемонстрировано в [18].
← →
Юрий Зотов © (2004-11-25 15:37) [27]> GuAV © (25.11.04 14:55) [26]
1. Согласен, что я плохо подумал, что мои представления о компиляторе оказались ошибочными, и что надо писать I absolute F.
2. Не согласен, что ДАННЫЙ код от этого становится плохо читаемым (в более сложных случаях - да, возможно, там и я тоже не стал бы злоупотреблять базированием, но ДАННЫЙ случай слишком прост и absolut"но прозрачен). Ссылку на "а что такое absolute" аргументом не считаю, поскольку в ней продемонстрирована не запутанность кода, а элементарное незнание языка. С таким же успехом можно сказать, что указатели тоже запутывают код, потому что не все понимают, что это такое.
3. В глубоких рекурсиях (а никогда нельзя знать, где и как будет использована твоя процедура) даже 1 байт стека может оказаться критичным. Поэтому, если есть возможность что-то сэкономить без ущерба для остального - стоит это делать.
← →
Юрий Зотов © (2004-11-25 15:38) [28]Удалено модератором
Примечание: дубль
← →
Sha © (2004-11-25 16:11) [29]> Bobby Digital © (24.11.04 05:02)
Не забудь только, что
TryStrToInt считает $1 и 0x1 целыми
TryStrToFloat считает 1E-10 плавающим
← →
GuAV © (2004-11-25 16:13) [30]Юрий Зотов © (25.11.04 15:38) [28]
Не согласен, что ДАННЫЙ код от этого становится плохо читаемым
Ок, согласен плохо читаемым не становится.
Юрий Зотов © (25.11.04 15:37) [27]
3. В глубоких рекурсиях (а никогда нельзя знать, где и как будет использована твоя процедура) даже 1 байт стека может оказаться критичным.
1 байт стека - это как ? :-)
Юрий Зотов © (25.11.04 15:37) [27]
Поэтому, если есть возможность что-то сэкономить без ущерба для остального - стоит это делать.
Однако шанс сделать ошибку - тоже "учерб для остального". Здесь конечно же вследствие absolut"ной прозрачности кода её обнаружить легко.
PS: Лично я бы предпочёл такой код:var
DummyParam: record
case TDataType of
dtInteger: (I: Integer);
dtFloat: (F: Double);
end;
← →
Sha © (2004-11-25 16:21) [31]Еще имеет смысл добавить const в описание параметра:
function GetDataType(const S: string): TDataType;
← →
jack128 © (2004-11-25 17:34) [32]Sha © (25.11.04 16:21) [31]
не имеет. Если только для читабельности.
← →
Sha © (2004-11-25 18:03) [33]jack128 © (25.11.04 17:34) [32]
Еще имеет смысл посмотреть в Debug Window :)
← →
GuAV © (2004-11-25 18:09) [34]jack128 © (25.11.04 17:34) [32]
procedure ValueStringParameter(S: string);
begin
ShowMessageFmt("ValueStringParameter. ref count = %D",
[PInteger((Integer(S)-8))^]);
end;
procedure ConstantStringParameter(const S: string);
begin
ShowMessageFmt("ConstantStringParameter. ref count = %D",
[PInteger((Integer(S)-8))^]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var S: string;
begin
S := StringOfChar("-", 5);
ShowMessageFmt("Caller. ref count = %D",
[PInteger((Integer(S)-8))^]);
ValueStringParameter(S);
ConstantStringParameter(S);
end;
← →
jack128 © (2004-11-25 18:49) [35]я знаю, но это же серьзно, ты же понимашь. Если бы шло копирование строки, то да.. А так.. Хотя если уж за каждый байт с стеке бороться, то может и имеет смысл ;-)
← →
jack128 © (2004-11-25 18:50) [36]jack128 © (25.11.04 18:49) [35]
я знаю, но это же НЕ серьёзно, ты же понимаешь.
← →
Sha © (2004-11-25 19:17) [37]jack128 © (25.11.04 18:50) [36]
Обрати внимание на пролог/эпилог процедуры.
С const получается намного короче и быстрее.
← →
TankMan © (2004-11-25 19:39) [38]Мдаааа...:)
absolut"но полезно вести такие вот дискуссии...сколько на пасскале уж мелких прожек переписал, а вот про absolute даже не слышал...
З.Ы.
Пользуясь случаем хочу сказать ЮЗ спасибо за рекомендованную книгу про создание компонентов в Delphi. Это именно та книга, которой мне не хватало. (не по теме, ну гдеж я еще мог поблагодарить человека :) )
← →
Германн © (2004-11-26 04:11) [39]Честно говоря раньше часто использовал absolute в контексте:
var
St : String;
LenSt : Byte absolute St;
Но тогда речь шла о паскалевских строках и при формировании этих строк удобнее было писАть LenSt:=N, чем St[0]:=Chr(N) или удобнее было писАть N:=LenSt, чем N:=Ord(St[0]);
Но другим алгоритмом типа absolute я пользуюсь до сих пор и не собираюсь от него отказываться. Это вариантный record. Он мне жизненно необходим, поскольку я получаю ответ от некоего железа. И этот ответ зависит от того, что у него запрашивают.
← →
GuAV © (2004-11-26 14:29) [40]Германн © (26.11.04 4:11) [39]
Но другим алгоритмом типа absolute я пользуюсь до сих пор и не собираюсь от него отказываться. Это вариантный record.
Это всё же IMHO лучше absolute. В этом случае и я бы им воспоьзовался - cм [30].
← →
Германн © (2004-11-27 00:58) [41]2 GuAV © (26.11.04 14:29) [40]
>var
> DummyParam: record
> case TDataType of
> dtInteger: (I: Integer);
> dtFloat: (F: Double);
> end;
Имхо, это все-таки не лучше absolute. Это просто другой путь имеющий свою ценность.
На Ваша реализация грешит явным переизбытком сущностей.
1. TDataType - явное излишество. Он никому не нужен никогда в данной ситуации.
2. Соответсвенно - dtInteger и dtFloat тоже.
Кроме того в более сложных ситуациях, которые упоминал я, необходимо использование волшебного слова packed.
А вообще-то есть пожалуй единственный плюс в Вашем варианте замены absolute на record. В нем неважен порядок перечисления вариантов.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.035 c