problemi di stringa durante la migrazione da Delphi 3 a Delphi 2010
-
29-10-2019 - |
Domanda
Ho avuto l'origine di un progetto più vecchio e devo cambiare piccole cose, ma ho avuto grossi guai perché avevo solo delphi 2010 per farlo.
È stato definito un record:
bbil = record
path : string;
pos: byte;
nr: Word;
end;
in seguito questa definizione viene utilizzata per leggere dal file:
b_bil: file of bbil;
pbbil: ^bbil;
l_bil : tlist;
while not(eof(b_bil)) do
begin
new(pbbil);
read(b_bil, pbbil^);
l_bil.add(pbbil);
end
Il problema principale è che il compilatore non accetta il tipo "stringa" nel record perché vuole una "finalizzazione". Così ho provato a cambiare "stringa" in "stringa [255]" o "shortstring".In questo modo l'app sta leggendo il file ma con contenuti errati.
La mia domanda è come convertire il vecchio tipo "stringa" con cui i file sono stati scritti nei "nuovi" tipi in Delphi 2010.
Ho già provato molto, ad es."{$ H-}".L'aggiunta di un solo carattere in più nel record mostra, il file è corretto, perché il file è letto quasi corretto ma troncato di un carattere in più per ogni set di dati - la lunghezza di lengthbyte + 255 caratteri sembra essere corretta per la definizione ma la stringa non corrisponde.
Soluzione
Eek! Sembra che il tuo codice sia precedente o non utilizzi stringhe lunghe. Se vuoi ottenere lo stesso comportamento del tuo vecchio Delphi, devi sostituire string
con ShortString
.
Vedo che l'hai già provato e segnalo che non riesce. È davvero l'unica spiegazione che abbia senso per me perché tutti gli altri tipi di stringa sono essenzialmente puntatori e quindi l'unico modo in cui il read
avrebbe potuto funzionare è con un ShortString
. La migrazione che stai tentando è immensa e probabilmente hai un numero enorme di problemi confondenti.
@LU RD fa un buon punto nei commenti sul fatto che il layout del record può differire tra le versioni di Delphi poiché non stai usando un array packed
. Puoi esaminare il layout del record utilizzando le due versioni di Delphi che hai a portata di mano. Dovrai fare in modo che la dimensione dei record corrisponda tra le versioni e che anche gli offset dei campi corrispondano.
In base ai commenti seguenti, l'aggiunta di un byte di riempimento tra pos e nr risolverà i tuoi problemi.
bbil = record
path : string;
pos: byte;
_pad: byte;
nr: Word;
end;
Puoi anche ottenere lo stesso effetto impostando il compilatore $ALIGN
opzione per {$ALIGN ON}
che sarebbe il modo in cui penso che farei le cose.
A lungo andare dovresti davvero allontanarti da stringhe brevi, codifica ANSI, mappatura diretta tra i tuoi record interni e i tuoi file di dati e così via. Nel breve periodo potrebbe essere meglio procurarsi la stessa versione di Delphi usata per costruire questo codice e usarlo. Mi aspetto che questo problema sia solo la punta dell'iceberg.
Altri suggerimenti
Basta ricordare:
"Stringa" <> "String [255]" <> "cortocallaggio" <> Ansistring
Indietro nei vecchi giorni di Dos / Turbo Pascal, "stringhe" erano davvero limitate a 255 caratteri. In gran parte perché il primo byte conteneva la lunghezza della stringa e un byte può avere un valore compreso tra 0 e 255.
Non è più un problema nelle versioni contemporanee di Delfi.
" cortaccia " è il tipo per il vecchio DOS / Pascal Tipo di stringa
"Longstring" è stato il tipo di stringa predefinito per un lungo periodo (incluso il Borland Delphi 2006 che attualmente uso per la maggior parte dei lavori di produzione). Da Delfi 3 .. Delphi 2009, Longstrings tenuto caratteri a 8 bit, ed erano limitati solo dalla memoria disponibile. Da Delphi 3 .. Delphi 2009, "Longstrings" sono stati sinonimi di "ansistres".
Versioni recenti di Delphi (Delphi 2009 e superiore, incluso il nuovo Delphi XE2) tutto ora predefinito per le stringhe "widestring" di Multi-Byte Unicode. widestrings , come gli ansistres, sono anche efficacemente "illimitate" nella lunghezza massima.
Questo articolo spiega più dettagliatamente:
http://delphi.about.com/od/begnerners/L/ AA071800A.htm
PS: Considera di usare "Sizeof (Bbil)" e " confezionato " per i record binari .
Forse sto trascurando qualcosa, ma, per come la vedo io, anche il tuo codice delphi 3 è guasto.Prova a determinare la dimensione del tuo record:
bbil = record
path : string;
pos: byte;
nr: Word;
end;
percorso (qualsiasi cosa tra 1 e 256 - un byte per la lunghezza, resto per i dati), pos (1 byte), nr (2 byte), facendo variare la dimensione dei dati del record da 1 + 1 + 2= 4 byte a 256+ 1 + 2= 259 byte.In quella circostanza, si otterrebbe comunque spazzatura dal file, dal momento che il programma non può ora quanti byte leggere, prima di leggere effettivamente i dati.Ti suggerisco di correggere il tuo record in modo che la stringa abbia una dimensione fissa, come:
path : ShortString[255];
Quindi, sarai in grado di scrivere e leggere bene sia in delphi 3 che nel 2010.