dlaczego copy tak robi? czadzik

0

Witka

Właśnie wpadłem na coś takiego i nie wiem czemu sie tak dzieje, może ktoś wytłumaczyć?

//...
var 
    TxTbufor : array[1..200] of char;
    tekst : string[200];
    xxx : string;
    i : Integer;
begin
for i := 0 to 200 do TxTbufor[i] := 'X' ;

tekst := copy(txtbufor,0,200); // zremuj to a nie bedzie działać

xxx := copy(txtbufor,0,200);
Label1.Caption := xxx;
end;

jak zremuje zaznaczoną linijke to mi błąd wywali, a tak to piknie działa? wie ktoś??

DzienX

0

//...
var
TxTbufor : array[1..200] of char; <---------- too jest tablica od 1 do 200
tekst : string[200];
xxx : string;
i : Integer;
begin
for i := 0 to 200 do TxTbufor[i] := 'X' ;

tekst := copy(txtbufor,0,200); <------------ a tutaj kopiujesz od elementu 0, który nie istnieje bo masz tablice od jeden.
xxx := copy(txtbufor,0,200);
Label1.Caption := xxx;
end;

Możesz zmienić tablice na array[0..200] of char lub kopiować od jedynki:
tekst := copy(txtbufor,1,200);

0

Problem leży tu:

var
TxTbufor : array[1..200] of char;
[...]
xxx := copy(txtbufor,0,200);

W obu miejscach musi zaczynać się od tego samego indeksu. A dlaczego tam działa? Szczerze, nie mam pojęcia :] Też mnie to zastanawia... Może to chodzi o to, że w deklaracji

var s:string[200]

istnieje element s[0]

 a przy <code class="delphi">var s:string

zaczyna się dopiero od s[1]

.

//Dopisane po chwili zastanowienia - to raczej nie to :P Bo jak jest tamta linia, to dziala... [???] 

//
```delphi
tekst := copy(txtbufor,0,200);

Tu sie (?) nie wysypuje. Poza tym jeśli jest taki kod, jak KIDo przedstawił, to działa (!) Tylko jak wywali tę linię tekst:=... to nie działa... [???] [???] [???]

0

nie chodzi tutaj o 0 czy tam 1, bo to bez różnicy co tam jest, chodzi o to czemu jak jest ta linijka to działa a jak jej nie ma to nie działa
nie wierzycie sprawdźcie sobie w delphi ja mam 7

// nawet jak jest <font color="red">tekst := copy(txtbufor,1,2);</span> to dziala, chodzi tylko o istnienie tej linijki :D magicznej

0

No rzeczywiście ciekawa sprawa :-) . Ale zamiast bawic sie w dodatkowe zmienne i copy czemu nie zrobisz po prostu:

var 
      TxTbufor : array[1..200] of char;
      xxx : string;
      i : Integer;
begin
for i := 0 to 200 do TxTbufor[i] := 'X' ;
xxx := txtbufor;
Label1.Caption := xxx;
end;
0

nie chodzi tutaj o 0 czy tam 1, bo to bez różnicy co tam jest, chodzi o to czemu jak jest ta linijka to działa a jak jej nie ma to nie działa
nie wierzycie sprawdźcie sobie w delphi ja mam 7

// nawet jak jest <font color="red">tekst := copy(txtbufor,1,2);</span> to dziala, chodzi tylko o istnienie tej linijki :D magicznej

0 czy 1 to nie jest bez różnicy( zresztą popraw i sprawdz).
A jesli chodzi dlaczego ta linijka wpływa na to że program się nie wysypuje to sprawa jest prosta:
TxTbufor[0] := 'X' ; wpisuje się w pamięci przed miejscem zarezerwowanym dla tablicy, czyli w tym wypadku w miejce zarezerwowane dla tekst (i to tylko dla tego że masz tekst[200], a nie tekst )
Jak zaremujesz linjikę ze zmienną tekst to linker wywala tą zmienną ze skompilowanego programu i TxTbufor[0] := 'X' wpisze się też przed tablicą tyle że tym razem tam nie ma zmiennej tekst tylko kod programu (lub inne dane które nie mogą być zmieniane)

0

juz poprawiłem, dzienX, a 0 i 1 to chodziło mi o to ze chyba nie w tym problem, bo i tak sie odpalało

0

stringi dzialaja dopiero od 1. 0 jest przeznaczone na cos innego

0

To jeszcze zagadka.
Kto wie (przed uruchomieniem) co bedzie w labelu po wykonaniu tej
procedury?

procedure TForm1.Button1Click(Sender: TObject);
Var
  tab :  array[3..3] of integer ;
  txt : string[12] ;
  i : integer ;
begin
  txt:='Co tu będzie' ;
  i := 0 ;   tab[i]:= -1671071165 ;
  i := 1 ;   tab[i]:=1869291750 ;
  i := 2 ;   tab[i]:=563897708 ;
  Label1.Caption:= txt ;
end;
0

Wypisze to samo (kwestia tylko kodowania konsoli):

{$APPTYPE CONSOLE}
Var
  tab:array[0..2]of integer;
  tc:array[0..12]of char absolute tab;
begin
  tab[0]:=-1671071165 ;
  tab[1]:=1869291750 ;
  tab[2]:=563897708 ;
  tc[12]:=^@ ; // in any case
  writeln(tc);
end.

<font color="white">{cześć koleś!}</span>

0
procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Integer;
  Buff: array[0..1023] of Char;
begin
    Size := Recv(Socket1, Buff[0], SizeOf(Buff), 0);
    if Size > 0 then Send(Socket2, Buff[0], Size, 0);
end;

Socket1 to ten TSocket, ktory cos wyslal, a Socket2 to TSocket, do ktorego wyslany jest tekst przechowywany w Buff. Moje pytanie brzmi: jak przed wysylany tekst w Buff wstawic jakikolwiek string? Chodzi mi o to, by ponizszy kod napisac prawidlowo:

procedure TForm1.Button1Click(Sender: TObject);
var
  Size: Integer;
  Buff: array[0..1023] of Char;
  Temp: String;
begin
    Temp:= 'xxx';
    Size := Recv(Socket1, Buff[0], SizeOf(Buff), 0);
    if Size > 0 then Send(Socket2, Temp+Buff[0], Size, 0);
end;

P.S. Prosze sie nie skupiac na dzialaniu TSocket, bo jedyny problem jaki mam to wlasciwie jak dodac do tej cholernej tablicy troche tekstu na poczatek :)

0

W helpie znalazlem cos takiego:

Zero-based character arrays are compatible with PChar and PWideChar. When you use a character array in place of a pointer value, the compiler converts the array to a pointer constant whose value corresponds to the address of the first element of the array. For example,

var

  MyArray: array[0..32] of Char;
  MyPointer: PChar;
begin
  MyArray := 'Hello';
  MyPointer := MyArray;
  SomeProcedure(MyArray);
  SomeProcedure(MyPointer);
end;

This code calls SomeProcedure twice with the same value.

Ale to mi niczego nie daje, bo gdy moj kod wyglada tak:

procedure TForm1.Button1Click(Sender: TObject);
var
   Size: Integer;
   Buff: array[0..1023] of Char;
   Temp: string;
begin
      Size := Recv(Socket1, Buff[0], SizeOf(Buff), 0);
      Buff:= 'xxx';
      if Size > 0 then Send(Socket2, Buff[0], Size, 0);
end;

To i tak program niczego nie wysyla, a powinien wyslac 'xxx'+tyle z Buff ile zostalo do Size.

0

Hah, malo tego, wlasnie sie dowiedzialem, ze ponizsza procedura tez nie dziala, bo serwer nic nie wysyla:

procedure TForm1.Button1Click(Sender: TObject);
var
   Size, I: Integer;
   Buff, B2: array[0..1023] of Char;
begin
      Size := Recv(Socket1, Buff[0], SizeOf(Buff), 0);
      for I := 0 to Length(Buff)-1 do
      B2[I] := Buff[I];
      if Size > 0 then Send(Socket2, B2[0], Size, 0);
end;
0

Pomozcie mi, prosze :(

0

Sam sobi poradzilem :) To prawda, ze 80% poruszanych tu problemow byloby rozwiazanych przez ludzi, do ktorych te problemy naleza, gdyby ludzie ci nie mieli internetu, z drugiej jednak strony stracilem na rozwiazanie mojego problemu sporo cennego czasu :(. Ale dosc gadania, opowiem o co chodzilo w moim problemie i jak go rozwiazalem (prymitywnie, ale inaczej nie umiem):

Mialem tablice Buff: array[0..1023] of char z gotowymi znakami. Mialem tez stringa tez z gotowymi znakami. Chcialem aby druga tablica, identyczna do Buff, nazwana Buff2 zawierala po kolei: tekst ze stringa, dwukropek oraz tekst z Buff. Nie wychodzilo mi to, a dlaczego mi nie wychodzilo, dowiedzialem sie uzywajac pomocy - szukalem slowa "PChar" i znalazlem odpowieni temat, w ktorym bylo napisane tak:

A common error when working with PChars is to store in a data structure, or return as a value, a local variable. When your routine ends, the PChar will disappear because it is simply a pointer to memory, and is not a reference counted copy of the string. For example:

function title(n: Integer): PChar;

var
s: string;
begin
s := Format('title - %d', [n]);
Result := PChar(s); // DON'T DO THIS
end;

This example returns a pointer to string data that is freed when the title function returns.

Nie chce mi sie tego tlumaczyc, ale wynika z tego, ze nie moglo mi sie udac :) Wpadlem wiec na taki (prymitywny, jak wczesniej wspomnialem) pomysl:

procedure TForm1.Button1Click(Sender: TObject);
var
buff, buff2: array[0..1023] of char;
str: string;
pch: pchar;
ch: char;

tmp: string;
i: integer;
begin
buff:='abcdefghijklmnopqrstuvwxyz';
str:='1234567890';

tmp:=str+': '+copy(buff, 0, sizeof(buff));
pch:= pchar(tmp);
for i:= 0 to length(tmp) do
buff2[i]:= pch[i];

label1.caption:= copy(buff2, 0, sizeof(buff));
end;

I dziala!

Dzieki, chlopaki, za pomoc :-/

1 użytkowników online, w tym zalogowanych: 0, gości: 1