Skopiowanie zawartości łańcucha znaków do zwykłej tablicy znaków

0

Czesc,
mam problem z ktorym nie moge sobie poradzic (albo dlatego, ze juz jest pozno ;) ).
mam dwie zmienne:

 
var
linia:string;
zdanie:array[0..1023] of char;

teraz tworze sobie jakas nowa zmienna: (w tym przypadku zawartowsc jak i sama tabela o nazwie tablica jest nieistotna-sa tam stringi)

 
linia:='Twoje imie:'+tablica[0]+'Twoje nazwisko: '+tablica[1];
zdanie:=linia;

I dostaje:

Incompatible types array and string

Nie moge sobie z tym poradzic bo kiedy robie od razu:

zdanie:='Jakis tam zwykly tekst';

To wszystko jest ok. Moze mi ktos pomoc?

pozdrawiam!

3

Dostajesz błąd, albowiem język nie pozwala na przypisywanie łańcuchów znaków do macierzy znaków - nie ma zdefiniowanego zachowania operatora przypisania w takim przypadku;

Przekopiować zawartość łańcucha do tablicy możesz za pomocą uniwersalnej procedury Move - ona pozwala na kopiowanie dowolnego bloku pamięci; Poniżej przykład kopiowania pamięci pomiędzy łańcuchem a macierzą:

var
  arrChars: array [0 .. 1023] of AnsiChar;
  strLine: AnsiString;
  intLen: UInt8;
begin
  strLine := 'copying memory test';
  intLen := Length(strLine);

  WriteLn('Line: "', strLine, '"');

  Move(strLine[1], arrChars[0], intLen);
  strLine := '';
  WriteLn('Line: "', strLine, '"');

  SetLength(strLine, intLen);
  Move(arrChars[0], strLine[1], intLen);
  WriteLn('Line: "', strLine, '"');

  ReadLn();
end.

Na wyjściu otrzymamy poniższą treść:

Line: "copying memory test"
Line: ""
Line: "copying memory test"

I tak ma wyjście wyglądać;

Co prawda użyłem dodatkowej zmiennej intLen, ale gdzieś trzeba zapamiętać długość łańcucha przed jego wyczyszczeniem, żeby później wiedzieć ile znaków z powrotem skopiować z macierzy arrChars do łańcucha strLine; Jest to naturalne, bez kombinacji;


Jeśli ktoś lubi kombinować, to nie musi używać dodatkowej zmiennej do przechowania długości łańcucha, a wzamian skorzystać z pewnego prawa; Najpierw za pomocą procedury FillChar wypełnić zerami (znakami null) całą tablicę arrChars, następnie (tak jak powyżej) skopiować łańcuch i wyczyścić go; Teraz nie mamy długości łańcucha nigdzie zapisanej, więc nie wiemy jaką długość ustalić łańcuchowi strLine; Nie wiemy, ale możemy sie dowiedzieć;

Zmienne typu PChar są wskaźnikami na znaki lub na ciągi znaków, zakończone znakiem null; Do pobrania długości łańcucha siedzącego pod wskaźnikiem służy funkcja StrLen; Całość wyglądać będzie tak:

var
  arrChars: array [0 .. 1023] of AnsiChar;
  strLine: AnsiString;
begin
  FillChar(arrChars[0], Length(arrChars), #0);
  strLine := 'copying memory test';

  WriteLn('Line: "', strLine, '"');

  Move(strLine[1], arrChars[0], Length(strLine));
  strLine := '';
  WriteLn('Line: "', strLine, '"');

  SetLength(strLine, StrLen(@arrChars[0]));
  Move(arrChars[0], strLine[1], Length(strLine));
  WriteLn('Line: "', strLine, '"');

  ReadLn();
end.

Na wyjściu dostaniesz to samo co we wcześniejszym przykładzie;

Jeśli więc jedna lokalna zmienna więcej przyprawia Cię o ból głowy, to możesz skorzystać z takiego sposobu; Ważne wtedy będzie to, że ostatni znak macierzy arrChars będzie musiał zawsze zawierać znak null - w przeciwnym razie funkcja StrLen nie znajdzie końca buforu, albo znajdzie randomowy null gdzieś w śmieciach sterty;

Tak więc masz dwa rozwiązania, ale wybierz pierwsze - drugie to bardziej ciekawostka.

0

Wielkie dzięki, o to chodziło :)

0

Dodam jeszcze, że w Delphi bardzo rzadko zachodzi potrzeba tworzenia takich tablic. Typ string jest sam w sobie tablicą char'ów i jeśli potrzebujesz użyć np. wskaźnika na char (co jest częste np. w bibliotekach) to wystarczy że rzutujesz PChar(tutaj_twoj_String) natomiast w drugą stronę przykładowo jeśli jakaś funkcja potrzebuje zwrócić ci jakiś napis powiększasz swojego stringa przez SetLength(tutaj_twoj_String, rozmiar_bufora) i później funkcji podajesz wskaźnik na 1 element stringa czyli @tutaj_twoj_String[1] i ew. zmniejszasz rozmiar ponownie funkcją SetLength do zwróconego rozmiaru.

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