Zmienna długość łańcucha w tablicy

Odpowiedz Nowy wątek
2011-10-24 19:40
0

Witam wszystkich, mam dość nietypowy pomysł / problem; Otóż chodzi o to, że projektuję klasę, która korzysta z dynamicznej dwuwymiarowej tablicy przechowującej tekst w postaci łańcucha typu ShortString; Niestety przechowując w tablicy np. nazwy lokalnych plików (bez nazw katalogów) wiadome jest, że nie potrzeba 256 znaków na to, wystarczyło by 50; Ale nie mogę tego zaprogramować na sztywno, potrzebuję w konstruktorze pobrać ilość znaków jaka będzie przypadać na każde pole, ale tylko raz, a później (w dalszej części konstruktora) w jakiś sposób utworzyć główną tablicę, która będzie właśnie przechowywać dane typu String[podana_długość];

Czy ma ktoś pomysł jak to zaprogramować? Bardzo proszę o podpowiedź;

Stworzona tablica musi być niewidoczna (sekcja private);


Pozostało 580 znaków

2011-10-24 23:15
0

A próbowałeś z array of array of Char?

Pozostało 580 znaków

2011-10-25 09:49
0

po co kombinować.
wystarczy zwykły string, który w zależności od wersji delphi jest tym samym co ansistring albo unicodestring.

string ma dynamicznie alokowaną pamięć.

problem nie istnieje.

edytowany 1x, ostatnio: Azarien, 2011-10-25 09:50

Pozostało 580 znaków

2011-10-25 16:50
0
Azarien napisał(a)

string ma dynamicznie alokowaną pamięć.

Racja, ma dynamicznie przydzielany odszar pamięci, ale właśnie chcę zmienić ze String na krótszy łańcuch;

Może po kolei; Tablica ta jest dwuwymiarowa, stąd można podczas korzystania z utworzonego wcześniej obiektu zmieniać jej rozmiar (zarówno pierwszego jak i drugiego wymiaru) odpowiednimi metodami; Ale gdy tablica posiada np. pięć kolumn i tysiąc wierszy metoda do odczytu pojedynczej komórki nie zwraca jej wartości mimo tego, że komórka o podanym adresie nie dość, że istnieje to jeszcze posiada jakąś wartość różną od pustego łańcucha; Nie wiem dlaczego tak się dzieje, ale obliczałem teoretyczny rozmiar tablicy w bajtach i nie jest aż tak duża - każda komórka przyjmowała łańcuch o długości trzech znaków; Z resztą metoda ta już nie odczytywała komórki o adresie [4][290], gdzie 4 to indeks kolumny, a 290 wiersza;

Niestety musiałem zaprojektować tablicę tak, by najpierw podawało się indeks kolumny (czyli 4), a później wiersza (tu 290) a AFAIK powinno być na odwrót; Inaczej nie mógłbym w ogóle korzystać z tablicy, ponieważ dopuszczana jest możliwość, gdy wiersze nie istnieją, a kolumny tak:

Length(Tablica) //zwraca ilość kolumn
Length(Tablica[0]) //zwraca ilość wierszy pod warunkiem, że Length(Tablica) zwraca wartość większą od 0

Ilość wierszy mogę odczytywać w ten sposób, ponieważ Tablica[0] istnieje zawsze, gdyż nie ma możliwości usunąć wszystkich kolumn, musi zostać co najmniej jedna; Jeżeli tablica jest pusta (tzn. nie posiada żadnych wierszy) musi być możliwość odczytu ilości kolumn, czyli Length(Tablica).

Wracając do pytania nie wiem, czy metoda nie odczytuje wartości pojedynczej komórki dlatego właśnie, że przeszkadza w czymś dynamiczne przydzielanie miejsca w pamięci dla łańcuchów typu String czy jest jakaś inna przyczyna; W każdym bądź razie pamięci RAM na pewno mi nie brakuje;

Czy statyczna długość łańcucha może wyeliminować ten błąd czy to nie tu jest bubel? Czy zmiana typu danych przechowywanych w tablicy rozwiąże ten problem? Bo jeżeli nie to dlaczego tak się właśnie dzieje?


edytowany 1x, ostatnio: furious programming, 2011-10-25 16:54

Pozostało 580 znaków

2011-10-25 19:12
0

Racja, ma dynamicznie przydzielany odszar pamięci, ale właśnie chcę zmienić ze String na krótszy łańcuch;

krótszy niż ile?
piszesz że nie chcesz marnować pamięci:

Niestety przechowując w tablicy np. nazwy lokalnych plików (bez nazw katalogów) wiadome jest, że nie potrzeba 256 znaków na to, wystarczyło by 50; Ale nie mogę tego zaprogramować na sztywno

otóż typ string da ci dokładnie taki efekt: stringi zajmujące tyle pamięci co potrzeba. nie trzeba nic dodatkowo kombinować.

Z resztą metoda ta już nie odczytywała komórki o adresie [4][290], gdzie 4 to indeks kolumny, a 290 wiersza;
zamieniłeś kolejność indeksów. stąd pewnie bierze się twój błąd.

edytowany 1x, ostatnio: Azarien, 2011-10-25 19:13

Pozostało 580 znaków

2011-10-25 22:46
0
Azarien napisał(a)

otóż typ string da ci dokładnie taki efekt: stringi zajmujące tyle pamięci co potrzeba. nie trzeba nic dodatkowo kombinować.

W takim razie skoro jest o wiele lepszy niż kombinowanie z ich długością to bardzo się cieszę;

Azarien napisał(a)

zamieniłeś kolejność indeksów. stąd pewnie bierze się twój błąd.

Masz jakiś pomysł jak ustawiając indeksy odwrotnie móc odczytać ilość kolumn gdy tablica jest pusta (czyli nie ma wierszy)?

PS: W sumie w pierwszych wersjach klasy podstawowym typem danych w tablicy był łańcuch String; Myślałem, że to on sprawia problemy i zmieniłem to, ale nie miało to znaczenia;


edytowany 2x, ostatnio: furious programming, 2011-10-25 22:47

Pozostało 580 znaków

2011-10-26 00:39
0
Furious Programming napisał(a)

Ale gdy tablica posiada np. pięć kolumn i tysiąc wierszy metoda do odczytu pojedynczej komórki nie zwraca jej wartości mimo tego, że komórka o podanym adresie nie dość, że istnieje to jeszcze posiada jakąś wartość różną od pustego łańcucha;

a co zwraca blad, "krzaczki"...? sprawdz czy oby na pewno odwolujesz sie do tej komorki, bo czasem wystarczy literowka jakas.
pamietaj o indeksowaniu tablic od zera.
powodem moze tez byc ze wpisujez dane da tablicy pod nieprawidlowym adresem -co nie wyrzuci bledu- i w efekcie masz namieszane w pamieci programu.

Furious Programming napisał(a)

W każdym bądź razie pamięci...

W każdym bądź razie :)

edytowany 2x, ostatnio: cimak, 2011-10-26 00:40

Pozostało 580 znaków

2011-10-26 10:01
0

Masz jakiś pomysł jak ustawiając indeksy odwrotnie móc odczytać ilość kolumn gdy tablica jest pusta (czyli nie ma wierszy)?

jak nie ma wierszy to nie ma „kolumn”. coś jest nie tak z twoim projektem.
zdecyduj się, czy chcesz dwuwymiarową tablicę znaków, czy tablicę stringów.

Pozostało 580 znaków

2011-10-26 19:49
0
cimak napisał(a)

a co zwraca blad, "krzaczki"...?

W tym rzecz, że nic, pusty łańcuch, brak wartości; Nie ma żadnego błędu, nie wyskakuje AV;

cimak napisał(a)

sprawdz czy oby na pewno odwolujesz sie do tej komorki, bo czasem wystarczy literowka jakas.

Sprawdzam indeksy czy istnieją w tablicy; Na dodatek jeżeli pobieram ilość kolumn i wierszy oraz wyświetlam ich wartości np. tak:

  ...

var
  iC, iR: Integer;
begin
  ....

  iC := Length(Tablica); //pobranie ilości kolumn
  iR := Length(Tablica[0]); //pobranie ilości wierszy

  MessageBox(PChar('Columns: ' + IntToStr(iC) + #10'Rows: ' + IntToStr(iR)), 'Counts', MB_OK);

  ...

zawsze pobierana jest właściwa ilość zarówno kolumn jak i wierszy; W ten sam sposób sprawdzam indeksy przed pobraniem wartości z danej komórki, więc nie mam pojęcia dlaczego zawsze przy indeksie wiersza większym niż mniej więcej 290 zwraca pusty łańcuch;

cimak napisał(a)

pamietaj o indeksowaniu tablic od zera.

A da się inaczej przy tablicach dynamicznych? :)

cimak napisał(a)

powodem moze tez byc ze wpisujez dane da tablicy pod nieprawidlowym adresem -co nie wyrzuci bledu- i w efekcie masz namieszane w pamieci programu.

Nie ma możliwości odwołać się do komórki, która nie istnieje, bo metody służące do wpisywania danych do komórek są zabezpieczone pod kątem właśnie nieprawidłowych indeksów;

cimak napisał(a)

W każdym bądź razie

Czy coś źle napisałem? :P

Azarien napisał(a)

jak nie ma wierszy to nie ma „kolumn”.

Właśnie; Chciałbym, by była możliwość odczytu ilości kolumn podczas gdy nie ma wierszy; Jeżeli zamienię indeksy - tej mozliwości nie będzie;

Azarien napisał(a)

coś jest nie tak z twoim projektem.

Dlaczego? Chcę tylko, by klasa była funkcjonalna;

Azarien napisał(a)

zdecyduj się, czy chcesz dwuwymiarową tablicę znaków, czy tablicę stringów.

Jestem zdecydowany; Potrzebuję przechowywać łańcuchy o dowolnej długości tylko chciałem użyć zamiast String typu 'array of Char'; W rezultacie deklaracja tablicy wyglądała by tak: Tablica: array of array of array of Char;; Wtedy długość każdej komórki (czyli array of Char) ustawiałbym ręcznie podczas wpisywania danych;

Dlaczego tak zadałem pierwsze pytanie? Ponieważ myślałem, że problem tkwi właśnie w korzystaniu z dynamicznych dwuwymiarowych tablic w połączeniu z łańcuchem zmiennej długości, lecz problem wcale ich nie dotyczy;


Pozostało 580 znaków

2011-10-26 20:02
0

W rezultacie deklaracja tablicy wyglądała by tak: Tablica: array of array of array of Char;

twoim problemem jest nie wyrażanie się w jasny sposób. teraz nagle się okazuje, że chciałbyś trójwymiarową tablicę znaków, czy tam dwuwymiarową tablicę stringów.

pokazujesz też za mało kodu. ani razu do tej pory nie pokazałeś jak definiujesz tablicę.

być może chodzi ci o array of array of string? nie będziemy wiedzieć, póki nie wyrazisz się jaśniej.

Pozostało 580 znaków

2011-10-26 20:15
0
pytanie tematu napisał(a)

Otóż chodzi o to, że projektuję klasę, która korzysta z dynamicznej dwuwymiarowej tablicy przechowującej tekst w postaci łańcucha typu ShortString;

Więc jak można zadeklarować taką tablicę?:

Tablica: array of array of ShortString;

Czy to nie to samo co:

Tablica: array of array of array of Char;

Teoretycznie tak, tyle że w drugim przypadku muszę ręcznie ustalać rozmiar tablicy stanowiącej komórkę (czyli array of Char to przecież w teorii to samo co String);

Azarien napisał(a)

twoim problemem jest nie wyrażanie się w jasny sposób.

Dzieje się tak dlatego, ponieważ ciężko mi dokładnie wytłumaczyć problem, a poza tym nie opiszę problemu tak, by każdy zrozumiał; Zawsze ktoś ma jeszcze jakieś wątpliwości; Wybaczcie za niejasności;


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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