2012-01-07 10 views
20

im pracy na Delphi 7 a ja pracuje nad strunami, natknąłem się na tenw jaki sposób delphi "ciąg" literałów może mieć więcej niż 255?

Przez ciąg domyślnej długości, czyli po prostu uznane jako ciąg znaków, max rozmiar jest zawsze 255. ShortString nigdy nie może wzrosnąć do więcej niż 255 znaków.

na delphi strings

raz musiałem zrobić coś takiego w moim delphi kodu (który był na naprawdę dużym zapytania)

var 
    sMyStringOF256characters : string; 
    ilength : integer; 
    begin 
     sMyStringOF256characters:='ThisStringisofLength256,ThisStringisofLength256,.....' 
     //length of sMyStringOF256characters is 256 
    end; 

uzyskać to error

[Błąd] u_home.pas (38): Literały łańcuchowe mogą zawierać maksymalnie 255 elementów.

ale gdy próbuję to

var 
     iCounter    : integer; 
     myExtremlyLongString : string; 
    begin 
     myExtremlyLongString:=''; 
     Label1.Caption:=''; 
     for iCounter:=0 to 2500 do 
     begin 
      myExtremlyLongString:=myExtremlyLongString+inttostr(iCounter); 
      Label1.Caption:=myExtremlyLongString; 
     end; 
     Label2.Caption:=inttostr(length(myExtremlyLongString)); 
    end; 

a wynik jest

enter image description here

Jak widać długość myExtremlyLongString jest znaków.

dlaczego delphi nie dało żadnego błędu mówiąc, że długość przekracza 255 dla myExtremlyLongString?

EDIT użyłem

SetLength(sMyStringOF256characters,300); 

ale nie robi praca.

+0

Może jesteś po prostu czytanie źle docs. BTW, to naprawdę niejasne, co masz na myśli przez "dynamicznie przypisany", a nie ... co? – OnTheFly

+0

@ user539484: znaczenie podczas pracy podczas pętli może być strVal: = mystring, podobnie jak wartość pętli przypisanie zmiennej łańcuchowej – PresleyDias

+1

ah, scratch "dynamicznie", a następnie jej przydział w porównaniu z deklaracją ** **. To, co cytujesz powyżej, dotyczy deklaracji, a dokładniej - ograniczenia kompilatora znaków ** literałów **. Został on podłączony do ciągów Turbo Pascal tylko środkami historycznymi. – OnTheFly

Odpowiedz

31

dlaczego nie delphi dać żadnego błędu mówiący długość wynosi ponad 255 dla myExtremlyLongString?

masz odpowiedź nieco w dół w tekście w sekcji długi ciąg (AnsiString).

W obecnych wersjach Delphi, typ ciąg jest po prostu aliasem AnsiString,

więc ciąg nie jest ograniczona do 255 znaków, ale ciąg jest dosłowne. Oznacza to, że możesz zbudować łańcuch dłuższy niż 255 znaków, ale nie możesz mieć wartości ciągu w kodzie dłuższym niż 255 znaków. Jeśli chcesz, musisz je podzielić.

sMyString:='ThisStringisofLength255'+'ThisStringisofLength255'; 
+0

to działa, dziękuję za wyjaśnienie i przykład – PresleyDias

2

Różnica polega na tym, że w pierwszym przykładzie kodu umieszczasz ciąg jako część kodu - ciąg literowy. Ogranicza to liczbę dozwolonych znaków.

W drugim przykładzie kodu generujesz go dynamicznie i nie umieszczasz go jako jednego dużego ciągu literowego.

Typ ciągu w Delphi (w przeciwieństwie do skrótów, które mogą mieć tylko do 255) może być tak duży jak pamięć.

+0

+1, "może być tak duża, jak twoja pamięć." To bardzo duży ciąg niż – PresleyDias

+1

Nie może być tak duża jak twoja pamięć. Największe typy ciągów Delphi są nadal ograniczone do 2 GB znaków. http://docwiki.embarcadero.com/RADStudio/XE3/en/String_Types – alcalde

7

podzielić go na:

sMyStringOF256characters := 
    'ThisStringis' + 
    'ofLength256' + 
    'And ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'ManyManyManyManyManyManyManyManyManyManyManyManyMany' + 
    'CharactersCharactersCharactersCharactersCharactersCharactersCharactersCharacters'; 
+1

+1, próbowałem już podobnego (mniej niż 255 na pewno), dla zapytania raz, tym razem myślałem, że limit wynosi 255, więc nie wykraczać poza 255..nice przykład thanx – PresleyDias

4

Powrót w starych DOS/Turbo Pascal dni "struny" zostały rzeczywiście ograniczone do 255 znaków. W dużej mierze dlatego, że pierwszy bajt zawierał długość ciągu, a bajt może mieć tylko wartość od 0 do 255.

To już nie jest problem we współczesnych wersjach Delphi.

"ShortString" to typ dla starego typu ciągów DOS/Pascal.

"LongString" to domyślny typ ciągu od długiego czasu (w tym Borland Delphi 2006, którego używam obecnie w większości prac produkcyjnych). LongStrings (inaczej "AnsiStrings") zawierają 8-bitowe znaki i są ograniczone tylko dostępną pamięcią.

Najnowsze wersje Delphi (Delphi 2009 i nowsze wersje, w tym nowe Delphi XE2) są teraz domyślnie wielobajtowe ciągi "WideString" Unicode. WideStrings, podobnie jak AnsiStrings, są również efektywnie "nieograniczone" w maksymalnej długości.

tym artykule opisano bardziej szczegółowo:

http://delphi.about.com/od/beginners/l/aa071800a.htm

+0

+1 za miłe wyjaśnienie – PresleyDias

+2

To już nie jest problem we współczesnych wersjach Delphi, z wyjątkiem dwóch miejsc; Literały ciągów oraz w indeksach dolnych, takich jak string [50], gdzie (oczywiście!) Limit wynosi 250 lub mniej, w przypadku, o którym wspomnę, limit wynosi 50. –

+0

@Warren P - jesteś absolutnie poprawny. Rozwiązaniem dla literałów łańcuchowych jest użycie składni "mystring" + "omówionej w innych wątkach. – paulsm4

0

Jeśli potrzebujesz naprawdę długi ciąg w Delphi można załadować go od innych zasobów niczym plików TXT lub po prostu zwykłego tekstu z dowolnym rozszerzeniem. Używam go i działa. Możesz tworzyć tabele tablic "jak w" używając numerów zwykłego tekstu. W kodzie delphi możesz to zrobić jako @arjen van der Spek, a inni mówią tylko.

Dla mnie, pliki z tekstem jak var na sformatowany -

sometext:string=
'txt...'+
'txt...'+
'txt...';

są złe dla przyszłej edycji.

zalety: możesz użyć dowolnego długiego tekstu.

minusy: Kod tekst jest otwarta, każdy może przeczytać, że otwierając plik w Notatniku itp

1

Można spróbować przy użyciu klasy StringBuilder:

procedure TestStringBuilder; 
var 
    I: Integer; 
    StringBuilder: TStringBuilder; 
begin 
    StringBuilder := TStringBuilder.Create; 
    try 
     for I := 1 to 10 do 
     begin 
      StringBuilder.Append('a string '); 
      StringBuilder.Append(66); //add an integer 
      StringBuilder.Append(sLineBreak); //add new line 
     end; 

     OutputWriteLine('Final string builder length: ' + IntToStr(StringBuilder.Length)); 
    finally 
     StringBuilder.Free; 
    end; 
end;