Newsgroup: it.comp.lang.delphi
Titolo: inserire char(0) in una stringa

ricercando una stringa in un file (ho trovato la routine che fa al
caso mio) ho il problema in oggetto
in pratica ricerco un sequenza di byte trasformati con "char(n)" in
stringa
il problema è che ho 6 byte + due byte 00 + due byte ... e la stringa
mi si ferma fino al primo byte 00 quindi, visualizzando la stringa ho
solo i primi 6 byte i restanti 4 (00 00 01 01) non vengono inseriti
nella stringa
stupidata mia o non c'è possibilità di soluzione ?

 mi si ferma fino al primo byte 00 quindi[...]
Ovvio, le long string in Delphi sono ASCIIZ.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

caso mio) ho il problema in oggetto
Tu no stai cercando "una stringa", tu stai cercando una sequenza 
arbitraria di byte. Se l'algoritmo che usi si basa su stringhe ASCIIZ 
non funzionerà.
Devi usare un buffer "generico" o un array (packed) di byte.
--- posted by geoForum on 
http://www.delphiedintorni.it


l'algoritmo al momento non c'entra ... semplicemente non vedo la
stringa completa con lo showmessage(string1)
ho provato anche settando la string1[12]
comunque controllando la lunghezze della stringa, questa è corretta
ps. la routine funziona con i byte credo
___________________________________________
function TMainForm.ScanFile(const FileName: string; const forString:
string; caseSensitive: Boolean): Longint;
const
  BufferSize = $8001;  { 32K+1 bytes }
var
  pBuf, pEnd, pScan, pPos: pChar;
  filesize: LongInt;
  bytesRemaining: LongInt;
  bytesToRead: Integer;
  F: file;
  SearchFor: pChar;
  oldMode: Word;
begin
  { assume failure }
  Result := -1;
  if (Length(forString) = 0) or (Length(FileName) = 0) then Exit;
  SearchFor := nil;
  pBuf      := nil;
  { open file as binary, 1 byte recordsize }
  AssignFile(F, FileName);
  oldMode  := FileMode;
  FileMode := 0;    { read-only access }
  Reset(F, 1);
  FileMode := oldMode;
  try { allocate memory for buffer and pchar search string }
    SearchFor := StrAlloc(Length(forString) + 1);
    StrPCopy(SearchFor, forString);
    if not caseSensitive then  { convert to upper case }
      AnsiUpper(SearchFor);
    GetMem(pBuf, BufferSize);
    filesize       := System.Filesize(F);
    bytesRemaining := filesize;
    pPos           := nil;
    while bytesRemaining > 0 do
    begin
      { calc how many bytes to read this round }
      if bytesRemaining >= BufferSize then
        bytesToRead := Pred(BufferSize)
      else
        bytesToRead := bytesRemaining;
      { read a buffer full and zero-terminate the buffer }
      BlockRead(F, pBuf^, bytesToRead, bytesToRead);
      pEnd  := @pBuf[bytesToRead];
      pEnd^ := #0;
      pScan := pBuf;
      while pScan < pEnd do
      begin
        if not caseSensitive then { convert to upper case }
          AnsiUpper(pScan);
        pPos := StrPos(pScan, SearchFor);  { search for substring }
        if pPos <> nil then
        begin { Found it! }
          Result := FileSize - bytesRemaining +
            Longint(pPos) - Longint(pBuf);
          Break;
        end;
        pScan := StrEnd(pScan);
        Inc(pScan);
      end;
      if pPos <> nil then Break;
      bytesRemaining := bytesRemaining - bytesToRead;
      if bytesRemaining > 0 then
      begin
        Seek(F, FilePos(F) - Length(forString));
        bytesRemaining := bytesRemaining + Length(forString);
      end;
    end; { While }
  finally
    CloseFile(F);
    if SearchFor <> nil then StrDispose(SearchFor);
    if pBuf <> nil then FreeMem(pBuf, BufferSize);
  end;
end; { ScanFile }

        pPos :=3D StrPos(pScan, SearchFor);  { search for substring }
La routine usa tipi e funzioni per stringhe null-terminated. Io non la 
userei per sequenze arbitrarie di byte, tutto quello che č usato 
considera $00 come terminatore di stringa.
Tutto quel codice č un po' vecchiotto (es. l'uso della vecchia 
interfaccia file al posto di uno stream, ad esempio...), e nemmeno 
performante (ci sono algoritmi molto piů veloci per cercare).



Non ne esci gestendola come stringa. ShowMessage ti tronca, 
giustamente, la stringa perché quella che tu gestisci NON è una 
stringa.
Chr(0) è lo "string terminator", appena lo trova tronca.

Chr(0) è lo "string terminator", appena lo trova tronca.
Attenzione che le stringhe Delphi (AnsiString) benché *compatibili* con 
le stringhe null terminated, non sono null terminated, ma usano la 
lunghezza della stringa. Se ad esempio provate questo codice:
const
  S = 'Questa è una'#0'prova';
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(S);
  ShowMessage(IntToStr(Length(S)));
end;
La prima ShowMessage visualizza solo 'Questa è una' perché ad un certo 
punto passa per un'API di Windows (DrawText) che si ferma ovviamente al 
primo null che incontra (ed è passata come PChar), ma la seconda 
restituisce 18, non 12, cioè la lunghezza della stringa incluso il 
carattere null.
Se si manipola un'AnsiString utilizzando solo funzioni AnsiString, i 
null non dovrebbero venire eliminati né terminare la stringa. Ovviamente 
le funzioni basate su PChar utilizzano il carattere 0 come terminatore.
Il problema può essere la visualizzazione, o si mostra il dump 
esadecimale, o si sostituiscono i caratteri non stampabili ad esempio 
con un punto *prima* della visualizzazione, come fanno molti editor 
binari di file.


grazie per le informazioni, anche se mi sarebbe molto più utile un
qualche esempio e/o una routine aggiornata :)
comunque ho in parte risolto ... non dico come per evitare
linciaggi ;)
se quindi definisco tutto come AnsiString dovrebbe funzionare meglio ?
scusate ma c'è qualche regola che dice di evitare di postare routine ?
(lo so come tutti quelli alle prime armi chiedere la pappa pronta non
è bello ... per fortuna c'è chi la pensa diversamente ... ed io credo
di rientrare tra questi ... ma vado OT dato che parlerei di cose non
inerenti il NG ... scusate)