Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26072
Рейтинг: 2122
#31: 2015-03-31 11:55:55 ЛС | профиль | цитата
По-хорошему, я бы рекомендовал переименовать компонент, к примеру, в RepeatChar или FillChar
карма: 22

0
Ответов: 4622
Рейтинг: 746
#32: 2015-03-31 11:58:38 ЛС | профиль | цитата
Это называется "StrPad"
карма: 26

0
Разработчик
Ответов: 26072
Рейтинг: 2122
#33: 2015-03-31 12:10:41 ЛС | профиль | цитата
Netspirit писал(а):
Это называется "StrPad"

Ну, можно и так, но никак не SetLength
карма: 22

0
Ответов: 9906
Рейтинг: 351
#34: 2015-03-31 13:14:20 ЛС | профиль | цитата
Netspirit писал(а):
То-есть, когда изменение строки, полученной по ReadString недопустимо (в каких случаях одна и та же TData используется в нескольких компонентах)?

Думаю, что win-ХАК недопустим вообще.
Мы же работаем "из гарантий". По крайней мере - должны.

Ну вот, например
#pas
procedure THIStrMask._work_doCompare;
var sstr,str,msk:string;
begin
sstr := ReadString(_Data,_data_Str);
str := sstr+#1;
msk := _prop_Mask+#1;
if (_prop_CaseSensitive = 1) then begin
CharLower(PChar(str));
CharLower(PChar(msk));
end;
......
Вообще-то, "единичка" мне тут и нафиг не упала... Просто не очень хотелось рыть рогом землю для создания той самой "персональной копии" строки с RefCount=1.
Хотя, наверняка - есть какая-нибудь функция из System...

А теперь предположим, что нет у нас еще элементов, которые поймали бы этот win-ХАК.
Типа, протестировали -- ай-ай-ай как все хорошо!

Вот именно такой подход и есть "радиолюбительство"...
Профессионально: достаточно увидеть отсутствие ГАРАНТИЙ того, что кто-то, когда-нибудь не использует повторно такую строку.
И не надо даже искать - есть уже такие элементы, или нет. Это не очень-то и важно.

В Инженерной культуре это называется: "Не планируй себе проблемы. Попробуй сначала справиться с теми, которые возникнут и без твоего планирования"

карма: 9

0
Ответов: 4622
Рейтинг: 746
#35: 2015-03-31 13:27:45 ЛС | профиль | цитата
Вот демонстрация того, как это изменение строки влияет на другие компоненты: code_35424.txt
(третье событие хаба должно выдавать то же, что и первое, но не выдаёт)
карма: 26

0
файлы: 1code_35424.txt [1.2KB] [560]
Разработчик
Ответов: 26072
Рейтинг: 2122
#36: 2015-03-31 14:15:45 ЛС | профиль | цитата
Получается из той же оперы, что в WinAPI нельзя пихать строку нулевой длины, те Pchar(s), при length(s)=0 вызывает крэш. Netspirit, попробуй отключить в своей схеме данные от Edit, тут же получишь RunTime Error
карма: 22

0
Ответов: 5227
Рейтинг: 587
#37: 2015-03-31 14:35:31 ЛС | профиль | цитата
Netspirit, проблема решаема http://delphi.scps.ru/string/str5234.htm

#pas
procedure THiAsmClass.doWork(var _Data:TData; index:word);
var
s: string;
begin
s := ReadString(_Data, Data1, ');
UniqueString(s);
CharLower(PChar(s));
_hi_OnEvent(onResult, s);
end;
карма: 4
Мой форум - http://hiasm.bbtalk.me/ схемы, компоненты...
0
Ответов: 4622
Рейтинг: 746
#38: 2015-03-31 14:41:05 ЛС | профиль | цитата
nesco писал(а):
Получается из той же оперы

Нет, это особенность самой CharLower (в справке описана интерпретация параметра).

А вот другая опера. Что в данном Inline Code получается, если в потоке нет данных? Правильно, переменной s присваивается пустая строка ''. Если бы вместо пустой строки дать какую-нибудь не пустую, CharLower должна бы отработать нормально. Но нет, потому что это константа. А константы где у нас расположены? В памяти только для чтения. И эта функция будет пытаться менять данные в памяти для чтения.
То-есть, CharLower(PChar('ABC')) недопустимо.

andrestudio писал(а):
проблема решаема
Конечно решаема. Разными способами. Вон у нас некоторые добавляют символ в конец строки.

Кстати, вот ещё способ:
SetLength(s, Length(s));

карма: 26

0
Ответов: 9906
Рейтинг: 351
#39: 2015-03-31 14:53:50 ЛС | профиль | цитата
nesco писал(а):
Получается из той же оперы, что в WinAPI нельзя пихать строку нулевой длины, те Pchar(s), при length(s)=0

Неправда твоя, nesco!
Pchar(s), при length(s)=0 -- честно-благородно выдает ненулевой указатель на нулевой символ.
Вот Pointer(s), при length(s)=0 -- действительно, выдает nil.

Как при этом будет вести себя WinApi -- MSDN читать надо... Всякое WinApi бывает.
Может все и кошерно будет
карма: 9

0
Разработчик
Ответов: 26072
Рейтинг: 2122
#40: 2015-03-31 15:48:30 ЛС | профиль | цитата
Galkov писал(а):
Pchar(s), при length(s)=0 -- честно-благородно выдает ненулевой указатель на нулевой символ.

А я ничего про указатели и не писал. Я просто констатировал факт, что CharLower выдает ошибку при пустой строке. Те вот такой код выдает ошибку

  s := ';
CharLower(PChar(s));

карма: 22

0
Ответов: 4622
Рейтинг: 746
#41: 2015-03-31 15:49:43 ЛС | профиль | цитата
Такой тоже даст ошибку:
s := 'ABC';
CharLower(PChar(s));

карма: 26

0
Разработчик
Ответов: 26072
Рейтинг: 2122
#42: 2015-03-31 16:04:47 ЛС | профиль | цитата
Netspirit писал(а):
Такой тоже даст ошибку:

А вот это тогда почему выдает

  s1 := 'A';
s := s1 + #0;
deleteTail(s, 2);
CharLower(PChar(s));

s, в данном случае, уже не ссылается на константу
карма: 22

0
Ответов: 4622
Рейтинг: 746
#43: 2015-03-31 16:20:28 ЛС | профиль | цитата
Так вроде ж выяснили выше: CharLower не любит строки с 0-вой длиной. Возможно по причине той же константы: при PChar(s) с 0-вой длиной Delphi передаёт в функцию валидный адрес, по которому лежит #00. Этот адрес, вероятно, лежит в области констант. Другие API функции это вполне нормально воспринимают, а вот CharLower может пытаться писать по этому адресу.

Если в последнем случае написать
CharLower(Pointer(s))
то ошибки не будет: в этом случае Delphi передаст не указатель на константный символ #00, а именно 0, как адрес строки. А согласно MSDN, если аргумент CharLower меньше $FFFF (в данном случае 0), то она считает аргумент одним символом, результат преобразования которого и возвратит (не запишет по адресу, так как был передан не адрес, а код символа):
s := Char(CharLower(Pointer(65)));

карма: 26

0
Разработчик
Ответов: 26072
Рейтинг: 2122
#44: 2015-03-31 16:29:36 ЛС | профиль | цитата
Netspirit писал(а):
Другие API функции это вполне нормально воспринимают

А в этом есть стопроцентная уверенность Может еще какая функция не любит строки нулевой длины
карма: 22

0
Ответов: 4622
Рейтинг: 746
#45: 2015-03-31 16:38:08 ЛС | профиль | цитата
По каждой функции идёт описание, как она себя ведет, если ей передать nil или строку 0-вой длины (а это не одно и то же).
Обобщить можно лишь так: если API функция изменяет содержимое переданного ей буфера (в описании многих функций можно встретить предупреждение, что функция изменяет данные в буфере), то в такие функции нельзя передавать:
- PChar(<константа>), Pointer(<константа>)
- PChar(s) с 0-вой длиной строки. Но в зависимости от функции можно передавать Pointer(s), что не исключает предыдущего случая.

Пример:
MessageBox(0, PChar('Text'), PChar(''), 0); // В качестве заголовка пустая строка (адрес строки 0-вой длины, состоящей из одного символа #00)
MessageBox(0, PChar('Text'), nil, 0); // В качестве заголовка 0-вой адрес (нет никакой строки, даже пустой) - система проставит стандартный заголовок

карма: 26

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)