[delphi] null terminated string

Pagina: 1
Acties:
  • 265 views sinds 30-01-2008
  • Reageer

  • Tom-my
  • Registratie: November 2000
  • Laatst online: 19-06 09:25

Tom-my

w03iz0rz

Topicstarter
Jows,

Ik ben wat aan het maken met een udpclient socket van indy, dat is niet zo het probleem, maar het gaat mij om de data die in ontvang.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TForm1.Button1Click(Sender: TObject);
const
  MsgStart    = #255#255#255#255;
var
  sData: string;
  piet : integer;
begin
  //(messages, players, details, rules)
  udpInfo.Send(MsgStart + 'players' + #0);
  try 

    sData := udpInfo.ReceiveString();
    txtData.lines.add(sData);
    showmessage(sdata);
  except
    on E:Exception do
      txtData.Text  := E.Message;
  end;
end;


(udpinfo = udpclient van indy, txtdata = tmemo)
Regel 12 geeft het complete data packetje door aan sData. Helaas zitten hier veel #0's in. Dus als ik die data aan de txtdata geef, krijg ik alles te zien tot de eerste #0. Beetje jammer want dan mis ik een hoop :P.

Wat me wel bleek in regel 14 staat de showmessage, wat wel intact blijft zijn het aantal caracters die het bericht bevat, want ik krijg een meerlijnige showmessage te zien.

Beetje duidelijk? :) Ik zoek dus een manier voor een 'container' die me wel alles na de #0's laat zien :/

"Then there was the man who drowned crossing a stream with an average depth of six inches."


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Delphi's (Ansi/Long)Strings zijn van vroeger uit niet null terminated, maar bewaren de lengte van de string. Omdat de winapi veel null terminated strings gebruikt worden de Delphi strings tegenwoordig wel altijd met een #0 afgesloten. #0 tekens in je string gaat dus ook gewoon goed binnen Delphi, zolang je maar geen functies aanroept die een null terminated string verwachten. ShowMessage is zo'n functie. Uiteindelijk wordt de string namelijk op het scherm getekend dmv DrawText(Canvas.Handle, PChar(Msg), Length(Msg)+1. Je tekens zitten nog allemaal wel in de string, maar je kan ze niet weergeven dmv ShowMessage.

Kortom: Het kan, maar pas op! Vooral met win32 functies.

Misschien is het veiliger je gegevens niet als string te beschouwen, maar echt als block/buffer van gegevens. Dan kom je ook niet zo snel in de verleiding het als (null terminated) string te benaderen.

We adore chaos because we like to restore order - M.C. Escher


  • Tom-my
  • Registratie: November 2000
  • Laatst online: 19-06 09:25

Tom-my

w03iz0rz

Topicstarter
euhm ja maar hoe gebruik ik het dan, ik snap het niet..

"Then there was the man who drowned crossing a stream with an average depth of six inches."


Verwijderd

Als je nu het volgende doet werkt het dan wel :
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure TForm1.Button1Click(Sender: TObject); 
const 
  MsgStart    = #255#255#255#255; 
var 
  sData: string; 
  piet : integer; 
begin 
  //(messages, players, details, rules) 
  udpInfo.Send(MsgStart + 'players' + #0); 
  try 

    sData := udpInfo.ReceiveString(); 

    txtData.Text(sData);  // het gaat om deze regel

    showmessage(sdata); 
  except 
    on E:Exception do 
      txtData.Text  := E.Message; 
  end; 
end;

[ Voor 4% gewijzigd door Verwijderd op 29-06-2003 21:12 ]


  • Domokoen
  • Registratie: Januari 2003
  • Laatst online: 20-08 17:57
Als je'm wil gebruiken kan je de #0 chars eruit filteren... ik neem aan dat je de rest wilt laten zien?

For i:=1 to Length(sData) do
if sData[i] = #0 then sData[i] = ' ';

En vervangen zijn de 0-chars. Ik weet niet wat je er anders mee wil doen?

  • Just_a_Gamer
  • Registratie: November 2001
  • Laatst online: 22:10
Verwijderd schreef op 29 June 2003 @ 21:11:
Als je nu het volgende doet werkt het dan wel :
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure TForm1.Button1Click(Sender: TObject); 
const 
  MsgStart    = #255#255#255#255; 
var 
  sData: string; 
  piet : integer; 
begin 
  //(messages, players, details, rules) 
  udpInfo.Send(MsgStart + 'players' + #0); 
  try 

    sData := udpInfo.ReceiveString(); 

    txtData.Text(sData);  // het gaat om deze regel

    showmessage(sdata); 
  except 
    on E:Exception do 
      txtData.Text  := E.Message; 
  end; 
end;
Sinds wanneer heeft een TMemo een method Text( ) ?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

FanToom schreef op 29 June 2003 @ 21:09:
euhm ja maar hoe gebruik ik het dan, ik snap het niet..
Hoe gebruik je wat dan? Hoe gebruik je een buffer ipv een string? Tja, geen idee wat jij met je gegevens wilt en waarom je er #0 tussen stopt. Waarschijnlijk om een structuur aan te geven. Nou zorg dan dat het ook snel in een classe of record structuur komt.

We adore chaos because we like to restore order - M.C. Escher


  • OxiMoron
  • Registratie: November 2001
  • Laatst online: 27-06 10:54
tja.. het beste zou zijn om met pionters de string in meerdere PChar's te lezen..
Maar je zou ook gewoon een functie kunnen schrijven zoals in VB splits of in PHP explode.

zo moeilijk is dat niet :)

Albert Einstein: A question that sometime drives me hazy: Am I or are the others crazy?


Verwijderd

Just_a_Gamer schreef op 29 June 2003 @ 21:21:
[...]


Sinds wanneer heeft een TMemo een method Text( ) ?
Dit heeft de TMemo al jaren toch misschien ff de helpfile lezen ?

Verwijderd

[quote]Verwijderd schreef op 30 juni 2003 @ 16:54:
[...]
[\quote]

Dit heeft de TMemo al jaren toch misschien ff de helpfile lezen ?
Het moet dan wel zijn memo1.text := sdata;

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 26-06 10:37

OZ-Gump

terug van weggeweest

Verwijderd schreef op 30 juni 2003 @ 16:54:
Dit heeft de TMemo al jaren toch misschien ff de helpfile lezen ?

Het moet dan wel zijn memo1.text := sdata;
En dus heeft een Memo nog nooit een method text gehad, hooguit een property text ;)

Ontopic:
Hoe staat het ermee? Waarschijnlijk is de opmerking van LordLarry nog de beste: beschouw je gegevens niet als een string, maar prop ze in een recordje. Maak een klasse aan met de benodigde/relevante gegevens en gebruik deze om de gegevens in te zetten

[ Voor 5% gewijzigd door OZ-Gump op 30-06-2003 17:08 ]

My personal website


  • Tom-my
  • Registratie: November 2000
  • Laatst online: 19-06 09:25

Tom-my

w03iz0rz

Topicstarter
Soz paar dagen druk geweest met een vriendin die het leuk vond om mijn pc apperatuur op te ruimen. :)

Maar overigens gebruik ik dit om informatie van gameservers af te halen. Specifiek voor counter strike in dit geval. Deze servers geven lief informatie terug als je ze queried. Helaas is dit meer een soort bytestream die terug komt (zoals je al eerder eigenlijk zei lordlarry). Aangezien ik een luie componenten gebruikende programmeur ben heb ik dit nog nooit gezien/ mee gewerkt.

Jullie hebben mee een goed eind opweggeholpen! Ik had later op de avond gevonden hoe ik die #0's eruit krijg. Was ff prutsen, maar uiteindelijk was het eigenlijk zeer simpel (like altijd).

Nu ben ik bezig met de data ontcijferen die ik terug gestuurd krijg, ik heb nu van iemand (weet niet meer wie, maar bedankt! :)) informatie gehad over game server querien, dus ik weet het/de format van de regels, nu nog zien te bedenken hoe ik byte informatie terug krijg in leesbare informatie :P.

En inderdaaad heeft een tmemo een .text, alleen vind ik persoonlijk dat geen fijne manier van werken.

"Then there was the man who drowned crossing a stream with an average depth of six inches."


  • Tomatoman
  • Registratie: November 2000
  • Nu online

Tomatoman

Fulltime prutser

Er is al eens een topic over Counterstrike gameservers geweest.

Een goede grap mag vrienden kosten.

Pagina: 1