-
Připojen obrázek. Proč je pole TestFolderInfo prázdné? Očekával bych dvě položky: Latina a 0
var TestFolderInfo: TStrings; procedure ... begin TestFolderInfo := TStringList.Create; for i:=0 to maxTestFolders-1 do begin; readln(f,line); TestFolderInfo.clear; try ExtractStrings([';'], [], PChar(line), TestFolderInfo); finally end; end; end;
Fórum › Delphi
ExtractStrings a TStrings
Ano, mám to zobrazené v kukátku a krokuju to v debugeru.
begin;
readln(f,line);
TestFolderInfo.clear;
try
ExtractStrings([';'], [], PChar(line), TestFolderInfo);
if (line='') or ( (line[1]='0') and (trim(line)='0;' ) ) then
begin
SubMenuItemsLoaded[pos] := false;
JazykyFolders[pos] := '';
JazykySelected[pos] := '';
continue;
end;
pos := JazykyIndexy.IndexOf(TestFolderInfo[0]);
if pos<>-1 then
begin
SubMenuItemsLoaded[pos] := true;
JazykyFolders[pos] := TestFolderInfo[0];
if not (DirectoryExists(TestyDir+'\'+JazykyFolders[pos])) then
begin
CreateDir(TestyDir+'\'+JazykyFolders[pos]);
showmessage('Adresář jsem zkusil vytvořit automaticky: '+TestyDir+'\'+JazykyFolders[pos]);
; JazykyFolders[pos] := '';
SubMenuItemsLoaded[pos] := false;
end
else
try
c := c-1; // potvrdit, že složka s jazykem byla asociována
JazykySelected[pos] := TestFolderInfo[2];
if TestFolderInfo[2]='0' then
JazykySelected[pos] := ''
else
if not (DirectoryExists(TestyDir+'\'+JazykyFolders[pos]+'\'+JazykySelected[pos])) then
begin
showmessage('Cesta testu nenalezena: '+TestyDir+'\'+JazykyFolders[pos]+'\'+JazykySelected[pos]);
JazykySelected[pos] := '';
end;
except
JazykySelected[pos] := '';
end;
end
else
begin // adresář není specifikován
JazykyFolders[pos] := '';
SubMenuItemsLoaded[pos] := false
end;
finally
end;
Tvůj kód jsem nezkoušel (neb se v něm nevyznám), ale tohle:
procedure Foo;
var
Str: String;
Line: TStringList;
i: Integer;
begin
Str := 'Latina;0';
Line := TStringList.Create;
try
WriteLn(ExtractStrings([';'],[],PChar(Str),Line));
WriteLn;
For i := 0 to Pred(Line.Count) do
WriteLn(Line[i]);
finally
Line.Free;
end;
end;
...funguje jak má. Takže chyba bude jinde.
#4 Sniper
No a mě toto nefunguje:
procedure Foo;
var
Str: String;
Line: TStringList;
i: Integer;
begin
Str := 'Latina;0';
Line := TStringList.Create;
ExtractStrings([';'],[],PChar(Str),Line);
Line.Free;
end;
To jsem jen zkrátil tvůj kód. V kukátku vidím Line = (). Stojím na řádku Line.Free;
procedure Foo;
var
Str: String;
Line: TStringList;
i: Integer;
ptest: PChar; // console: warning Unsafe type PChar
begin
Str := 'Latina;0';
Line := TStringList.Create;
try
ptest := PChar(Str); // // console: warning Unsafe type PAnsiChar
ExtractStrings([';'],[],PChar(Str),Line);
finally
Line.Free;
end;
end;
Viz comment, funkce vrací typ PAnsiChar
Proměnné pTest je ve chvíli, kdy se na ní díváš, už nepřístupná/neexistuje. Ano, je to optimalizace, aby tam proměnný nezacláněli dýl, než je třeba.
Blok try-finally má svůj důvod - memory leak ti nic neříká?
Nebezpečný type casting ti to hlásí proto, že referencuješ obsah managed typu, tudíž nemáš vůbec žádnou kontrolu nad jeho obsahem mimo kód kde se používá.
Dobře, tak už chápu. Je to objekt, tedy se k tomu nedá přistupovat jako k poli.
Řeším tedy jak zkopírovat položky do pole nebo jak zkopírovat string z položky i do jiného stringu (tedy jak zpřístupnit ten string pomocí i).
Edit:
Tak zpřístupnit to mohu pomocí
Line.Strings[0], Line.Strings[1]
A když mám pole stringů
Jazyky : Array [0..maxTestItems-1] of string; // celkem 11 položek, ale iniciuje se jich jen 10, protože v souboru ze kterou čtu jazyky je jen 10 položek.
provedu iniciaci / načtení jazyků do pole...
A na konci pomocí smyčky přiřazuju str := ...
for i:=0 to maxSubFolders-1 do
begin;
j := length(submenuitems); // i - index submenu
setlength(submenuitems,j+1);
str := Jazyky[i];
// dále zpracuju str...
// a při 11 položce to krachne
end;
Jak zkontrolovat jestli Jazyky[i] je nastaveno ještě před tím než to zkusím přiřadit tomu str?
Konkrétně mi to dává hlášku: Access violition at address ...
To pole je automaticky naplněné prázdnými stringy. Spíš bych tipnul, že máš index 11, ale počítáno od 0 je to 12. položka, takže mimo pole. Samozřejmě můžeš použít Length, resp. Low/High pro testování platnosti indexu.
Se zapnutými "range checks" {$R+} by to mělo hodit vyjímku, ale jinak to klidně vezme neplatnou hodnotu jako string a klekne to až na Access Violation když s ním něco děláš. Takže alespoň pro ladění to doporučuji zapnout.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Kolize v Allegru — založil Dfire
Nespolupracuje Apache a MYSQL — založil kroky
Aplikace v C++ (jak ji naimplementovat formou webové služby?) — založil Zuzka
Řazení podle české abecedy — založil fix