Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];
Внизиз array Найти похожие ветки
← →
Zirus (2003-04-25 09:44) [0]Здравствуйте! Есть массив char-ов известной длины, в нём последовательно идут записи(текст), разделяющиеся через chr(0). Требуется кодом наименьшей длины запихать эти записи в pchar.
← →
evvcom (2003-04-25 09:51) [1]Сам то до конца понял, что спросил? В теме одно, в вопросе немного другое. Приведи уж декларацию своих массивов char/pchar
← →
Palladin (2003-04-25 09:53) [2]каким образом он получается?
может имеет смысл получать данные сразу в нужном виде?
← →
Anatoly Podgorestky (2003-04-25 09:55) [3]Оно в исходном виде уже совместимо с PChar
← →
Palladin (2003-04-25 09:56) [4]
> evvcom © (25.04.03 09:51)
все нормально описано
идет цепочка байтов
нужно получить указатели на элементы после каждого встречного #0
← →
REA (2003-04-25 10:00) [5]TStringList не разобьет?
← →
Anatoly Podgorestky (2003-04-25 10:05) [6]Разобьет конечно и количество посчитает.
← →
pasha676 (2003-04-25 10:05) [7]Вопрос некоректен.
Как привести массив из символов в массив из строк? Да никак. Тебя будет строка=одному символу (тогда и огород городить не надо). Можно оставить и без изменений.
← →
Anatoly Podgorestky (2003-04-25 10:06) [8]Но возможно и нет, поскольку речь идет об array[] of char
← →
evvcom (2003-04-25 10:07) [9]> Palladin © (25.04.03 09:56)
Может быть, но не совсем. То ему надо это "перевести в array[] of pchar", а то "запихать эти записи в pchar". То ли он хочет обращаться к array of array of char, как к array of pchar, то ли "запихать" в один pchar, то есть сложить?
← →
Digitman (2003-04-25 10:20) [10]
var
src: array[0..7] of Char = ("A", #0, "B", #0, "C", #0, "D", #0);
procedure TForm1.Button4Click(Sender: TObject);
var
List: TList;
i: Integer;
s: String;
begin
List := TList.Create;
try
i := Low(Src);
repeat
List.Add(@Src[i]);
i := i + Succ(strlen(@src[i]));
until i >= High(Src);
for i:= 0 to List.Count - 1 do
s := s + PChar(List[i]) + #10;
showmessage(s);
finally
List.Free;
end;
end;
← →
kostik78ua (2003-04-25 10:38) [11]Могу привести код процедуры, перевода строки с разделителями в Strings. Если его немного видоизменить, получишь то что тебе надо.
function StrToStrings(theString: string; Separator: char; Strings: TStrings): boolean;
var
P, P1: PChar;
strValue: string;
begin
if (theString<>"") and (theString[length(theString)]<>Separator) then
theString:=theString+Separator;
Strings.Clear;
P := PChar(theString);
while P^ <> #0 do
begin
P1 := P;
strValue:="";
while (P^ <> Separator) do P := CharNext(P);
SetString(strValue, P1, P - P1);
Strings.Add(strValue);
P := CharNext(P);
end;
Result:=true;
end;
← →
Zirus (2003-04-25 12:06) [12]Поясняю вопрос. Имеем приём из сетки закодированных сообщений UDP. После раскодирования будет вид: string1+chr(0)+string2+chr(0)+string3+chr(0)+string4+chr(0)+... до 100 записей, кол-во записей всё время разное, длина записи - тоже ранзая каждый раз(размер неизвестен, сигнал об окончании записи - chr(0)).
Во код:
procedure TPluginForm.Receive(Sender: TComponent;
NumberBytes: Integer; FromIP: String; Port: Integer);
var
x: integer;
buff: array [1..20000] of char;
TmpStr: String;
dd: array[1..100] of pchar;
begin
nmudp1.ReadBuffer(buff,numberbytes);
tmpStr:="";
for x:=1 to numberbytes do tmpstr:=tmpstr+buff[x];
tmpstr:=decode(tmpstr);
//тут надо из раскодированного tmpstr выделить array[1..100] of pchar, (т.е. dd: array[1..100] of pchar, см выше)
...
end;
Вопрос состоит в том, можно ли составить массив dd примерно таким образом: dd:=tmpstr
предыдущий код(var другой) выделяет начиная со второго символа записи в string. Можно конечно сделать pchar(mystring), но требуется уменьшить код.
{for x:=1 to 100 do dd[x]:="";
y:=2;
z:=1;
while y<=length(tmpstr) do begin
while (y<=length(tmpstr)) and (tmpstr[y]<>chr(0)) do begin
if z<100 then dd[z]:=dd[z]+tmpstr[y];
y:=y+1;
end;
y:=y+1;
z:=z+1;
end;
← →
Anatoly Podgorestky (2003-04-25 12:12) [13]А как ты определяешь окончание блока записей или всегда фиксированая длина в 101 байт. Это то что я имел ввиду Anatoly Podgorestky (25.04.03 10:06)
Если длина блока известна, то это тривиальное сканирование/копирование
← →
Zirus (2003-04-25 12:14) [14]известно, что длина блока записей не более 100 шт. обычно даже не более 5-10 шт. Все записи>100 обрезаем.
← →
Palladin (2003-04-25 12:16) [15]а нельзя переписать раскодирование что бы TStringList возвращался?
или хотя бы разделитель был не #0
тогда с задачей TStringList справится при использовании Delimiter
← →
Digitman (2003-04-25 12:17) [16]
> Zirus
чем тебе не нравится предложенное мной решение ?
← →
Zirus (2003-04-25 12:17) [17]Скажу даже так. Код, представленный ниже, выделяющий массив dd[1..100] of string, используемый после совместно с функцией pchar(dd[x]) - является оптимальным?
for x:=1 to 100 do dd[x]:="";
y:=2;
z:=1;
while y<=length(tmpstr) do begin
while (y<=length(tmpstr)) and (tmpstr[y]<>chr(0)) do begin
if z<100 then dd[z]:=dd[z]+tmpstr[y];
y:=y+1;
end;
y:=y+1;
z:=z+1;
end;
← →
Zirus (2003-04-25 12:19) [18]>Digitman
слишком длинное. длиннее чем у меня, а мне надо уменьшить код.
← →
evvcom (2003-04-25 12:20) [19]Во-первых, если decode своя, то в нее точно также можно передать buff и numberbytes и не извращаться с
for x:=1 to numberbytes do tmpstr:=tmpstr+buff[x];
← →
Palladin (2003-04-25 12:21) [20]
> Zirus © (25.04.03 12:19)
не в строчках счастье, а в качестве
← →
evvcom (2003-04-25 12:21) [21]Если decode - чужая и изменить нет возможности можно оптимизировать код, используя SetLength и Move
← →
Digitman (2003-04-25 12:24) [22]
> Zirus
чего "длинное" ?? вот это ???
List := TList.Create;
try
i := Low(Src);
repeat
List.Add(@Src[i]);
i := i + Succ(strlen(@src[i]));
until i >= High(Src);
....
finally
List.Free;
end;
)))))
← →
Anatoly Podgorestky (2003-04-25 12:24) [23]Zirus © (25.04.03 12:19)
А что случилось, для микроконтроллера пишешь?
← →
Zirus (2003-04-25 12:32) [24]>Palladin. Качество должно быть "по разумной цене" :-)
>evvcom. Decode своя. спасибо, код уменьшился на 1 строчку :-)
← →
Zirus (2003-04-25 12:35) [25]>Digitman. да, это слишком длинно.
>Anatoly Podgorestky. пишу чат.
← →
evvcom (2003-04-25 12:38) [26]Всякие y:=y+1; замени на Inc(y); - тоже оптимизация.
← →
Digitman (2003-04-25 12:38) [27]
> Zirus
ты, наверно, заболел)
тело цикла из двух простейших по логике строчек и безо всяких стринговых преобразований - и это "длинно" ты считаешь ?!... ну-ну))
← →
Palladin (2003-04-25 12:42) [28]
> Digitman © (25.04.03 12:38)
человек считает что чем меньше строчек
тем меньше программа занимает в памяти
и быстрей работает
наверно не стоит его разубеждать
← →
Zirus (2003-04-25 12:43) [29]>Digitman. мне бы лучше 10-этажное нагромождение процедур, зато в 3 строчки.
← →
Digitman (2003-04-25 12:45) [30]
> Zirus
коль уж ты заговорил об "оптимизации", имей ввиду, что операции (конкатенации, например) над строками в формате AnsiString ведут как правило к неконтролируемому тобой перераспределению памяти, что отнимает значительную долю времени и дефрагментирует внутр.структуры менеджера памяти
← →
evvcom (2003-04-25 12:48) [31]Кстати можно после ; не нажимать Enter, тогда все уместится в одной строке
← →
Digitman (2003-04-25 12:49) [32]
> Zirus
точно - заболел) ...
ты рассуждаешь о какой-то там "оптимизации", совершенно не понимая при этом, что на самом деле сделает компилятор из твоих 3-х строчек)
ну уж ежели на то пошло, я тебе даже меньше предлагаю - всего 2 строчки !))... и при этом - достатачная оптимальность с т.з. минимизации скрытых перераспределений памяти
← →
evvcom (2003-04-25 12:51) [33]А теперь серьезно, если не хочешь TList, то хотя бы идею i := i + Succ(strlen(@src[i])); из примера Digitman используй. Это гораздо оптимальнее, чем твоя конкатенация
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.05.08;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.008 c