Как в памяти склеить word, string и символ 00h в строку?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Как в памяти склеить word, string и символ 00h в строку?

Сообщение nic1982 » 28.02.2019 18:06:56

Как в памяти склеить word, string и символ 00h в строку и получить на нее указатель?

Есть указатель (не типизированный pointer) на строку из шести байт, которая находится в оперативной памяти.
Код: Выделить всё
ZZTTT0
ZZ - первые два байта это word в котором содержится размер всей строки (ZZ + T...T + 00h)
T - это char которых может быть до 64 тысяч
0 - в конце каждой строки 00h означает конец строки


Вычитываю строку так
Код: Выделить всё
var
  p : pointer;
  s : string;
begin
  p:= super_get;
  s:= String(PChar(p+2)); // +2 это смешение для того чтобы не было мусорных символов из за размера
end;


Как мне из своего string получить такую же строку?
Код: Выделить всё
var   
  s : string;
  z : word;
  p : pointer;
begin
  s:= 'my text';
  z:= 2 + length(s) + 1; // два байта для размера, Х байт для текста и один для 00h
  getmem(p, z);
 
  p:= ? // как мне склеить z - размер, s - текст и 00h

  super_set(p, z);
  freemem(p);
end;


Функции super_get и super_set не мои и отказаться от их использования я не могу.
nic1982
новенький
 
Сообщения: 48
Зарегистрирован: 17.05.2011 16:34:05

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение Дож » 28.02.2019 18:25:53

Код: Выделить всё
Move(ZZ, p^, SizeOf(Word));
Move(S[1], (PByte(p) + SizeOf(Word))^, Length(S));
(PByte(p) + z - 1)^ := 0;
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение iskander » 28.02.2019 18:36:26

Код: Выделить всё
PWord(p)^ := z; 
StrPCopy(PChar(p + 2), s);

Пардон, опоздал.
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение nic1982 » 01.03.2019 10:03:34

Спасибо Дож и iskander за помощь.
nic1982
новенький
 
Сообщения: 48
Зарегистрирован: 17.05.2011 16:34:05

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение olegy123 » 02.03.2019 10:50:49

Я бы использовал так
Код: Выделить всё
type
  TPack = packed record
     Size:Word;
     Data:array of char;
  end;
  PPack=^TPack;

function pack(text:string):PPack;
var
  len:Word;
begin
   len:=Length(S);
   Result:=getMem(len+sizeof(word)+1);
   Result^.Size:=len;
   StrPCopy(Result^.Data,text);
end;

function unpack(pack:PPack):String;
begin
   Result:=PasStr(pack^.Data);
end;


писанины больше, но при больших данных и отладке Lazarus знает что показать в каких полях.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение Дож » 02.03.2019 14:34:15

olegy123, а отладка этой писанине нужна уже сейчас: Data в структуре имеет размер указателя, поэтому getMem(len+sizeof(word)+1) выделит неправильный размер памяти под структуру, а попытка записать что-то в Result^.Data без выделения памяти под массив через SetLength крашнет прогу.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение olegy123 » 02.03.2019 22:11:22

работает

Код: Выделить всё
  TPack = packed record
     Size:Word;
     Data:array [0..15] of char;
  end;
  PPack=^TPack; 

..


function pack(text:string):PPack;
var
  len:Word;
begin
   len:=Length(text);
   Result:=getMem(len+sizeof(word)+1);
   FillByte(Result^,len+sizeof(word)+1,0);
   Result^.Size:=len;
   move(text[1],Result^.Data,len);
end;

function unpack(pack:PPack):String;
begin
   SetLength(Result,pack^.Size);
   move(pack^.Data,Result[1],pack^.Size);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s1,s2:String;
  pp:PPack;
begin
   s1:='1234567890';
   pp:=pack(s1);
   s2:=unpack(pp);
   Freemem(pp);
end;           


отладчик pp:=pack(s1); показывает:
record TPACK {
SIZE = 10,
DATA = '1234567890'#0#0#0#0#0}


Добавлено спустя 1 минуту 27 секунд:
проблема в том что обычные процедуры работают с WString и WChar
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение Лекс Айрин » 02.03.2019 22:35:07

olegy123, вообще-то массив символов не эквивалентен строке, так что в данном контексте код бесполезен. Плюс, не стоит забывать, что кодировка может быть как однобайтовой, так и многобайтовой, а следовательно может привести к ошибке, если присвоить символу значение равное национальной букве. Стоит все же учитывать, что в лазаруса нормой является utf8. И, если уж так хочется массив, так сделай его открытым, чтобы вместить строки переменной длинны.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение Дож » 03.03.2019 09:34:42

olegy123, если работает, то зачем втихую Data:array of char менять на Data:array [0..15] of char? :)

И что же это за волшебная константа "15"?
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение Лекс Айрин » 03.03.2019 09:53:22

Дож, если я правильно помню, это максимальная длинна нормального слова (есть и подлиннее, но их ещё поискать надо). Хотя я тогда бы уж взял не меньше 50, а ещё лучше все 256
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение olegy123 » 03.03.2019 13:45:17

Дож писал(а):И что же это за волшебная константа "15"?

чтобы видно было..
record TPACK {
SIZE = 10,
DATA = '1234567890'#0#0#0#0#0}

чтобы DATA выводилось 15 символов при отладке..
65000 ругается, что очень много букв.

Result:=getMem(len+sizeof(word)+1); тут выделяется память с len букв + 2 на значение Word + 1 на #0
т.е. где то в памяти будет так ([2-Size]+[ ... len - длина string ...]+[1- символ #0])
с этими полями можно работать обычно через тип TPack

Добавлено спустя 1 минуту 34 секунды:
при этом эти данные будут упакованными..
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: Как в памяти склеить word, string и символ 00h в строку?

Сообщение Лекс Айрин » 03.03.2019 23:49:16

olegy123, не будут. Упаковка записей работало в ранних версиях Паскаля. Потом перестали.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot], Yandex [Bot] и гости: 8

Рейтинг@Mail.ru