2012-01-16 26 views
5

Ho avuto la fonte di un progetto più vecchio e devo cambiare piccole cose ma ho avuto grossi problemi a causa del solo delphi 2010 per farlo.problemi di stringa migrare Delphi 3 a Delphi 2010

C'è un record definito: dopo

bbil = record 
    path : string; 
    pos: byte; 
    nr: Word; 
end; 

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 è, il compilatore non accetta il tipo "stringa" in il record perché vuole una "finalizzazione". Così ho provato a cambiare "stringa" in "stringa [255]" o "stringhe". In questo modo l'app sta leggendo il file ma con contenuti errati.

La mia domanda è come convertire il vecchio tipo "string" con cui sono stati scritti i file per i "nuovi" tipi in Delphi 2010.

ho già provato un sacco per esempio "{$ H-}". Aggiungendo solo un carattere in più nel record, il file è corretto, poiché il file viene letto quasi corretto ma troncato un carattere in più ogni set di dati - la lunghezza della lunghezza + 255 caratteri sembra essere corretta fpr la definizione ma la stringa non corrisponde.

+0

Utilizzando AnsiString nel la definizione della registrazione risulta anche in un errore del compilatore: "la finalizzazione di bbil è necessaria". Abbreviando questi AnsiString in questo modo "pfad: AnsiString [255];" non funziona anche: "; atteso ma [trovato". Quello di cui ho probabilmente bisogno è una ShortAnsiString? – rseffner

+2

IMO il tuo codice non dovrebbe essere compilato anche in Delphi 3; prova 'path: array [0..N] di AnsiChar;', dove N è un costante, forse 255. – kludg

+2

Fai come dice David, dichiara la stringa come 'ShortString'. Per l'allineamento del record, provare la direttiva del pacchetto compresso se ciò aiuta. Perché questo codice abbia funzionato in D3, deve essere stata utilizzata la direttiva {$ H-}. –

risposta

5

Eek! Sembra che il tuo codice sia precedente o non usi stringhe lunghe. Se si desidera ottenere lo stesso comportamento del vecchio Delphi, è necessario sostituire string con ShortString.

Vedo che l'hai già provato e segnala che non funziona. È davvero l'unica spiegazione che ha senso per me perché tutti gli altri tipi di stringhe sono essenzialmente dei puntatori e quindi l'unico modo in cui il read potrebbe mai funzionare è con un ShortString. La migrazione che stai tentando è immensa e probabilmente hai un numero enorme di problemi di confusione.

@LU RD rende un buon punto nei commenti che il layout del record può differire tra le versioni Delphi poiché non si utilizza un array packed. Puoi esaminare il layout del record usando le due versioni di Delphi che hai a portata di mano. È necessario disporre che le dimensioni dei record corrispondano tra le versioni e che anche le correzioni ai campi corrispondano.

In base ai commenti seguenti, l'aggiunta di un byte di riempimento tra pos e nr risolverà i problemi.

bbil = record 
    path : string; 
    pos: byte; 
    _pad: byte; 
    nr: Word; 
end; 

Si potrebbe anche ottenere lo stesso effetto impostando l'opzione $ALIGN compilatore di {$ALIGN ON} che sarebbe come penso vorrei andare le cose.

A lungo termine, dovresti davvero scappare dalle stringhe brevi, dalla codifica ANSI, dalla mappatura diretta tra i tuoi record interni e i tuoi file di dati e così via. Nel breve periodo potrebbe essere meglio ottenere la stessa versione di Delphi utilizzata per creare questo codice e utilizzarlo. Mi aspetto che questo problema sia solo la punta dell'iceberg.

+0

David, penso che il consiglio 'ShortString' sia corretto, solo la dimensione del record deve corrispondere. Una direttiva di allineamento può risolvere questa o forse la dichiarazione di registrazione imballata. –

+0

L'utilizzo di ShortString come sostituzione di "String" nel recordset è stata una delle prime cose che ho fatto. Ma non funziona come previsto, tutti leggono datarecords erano spazzatura ;-(Devo leggere la "direttiva record compresso" - perché non lo so. – rseffner

+1

Basta dichiarare il tipo "record compresso" invece di "record". rimuoverà gli allineamenti effettuati dal compilatore. Per vedere le dimensioni del record, prova a usare 'SizeOf (bbil)'. –

2

Basta ricordare:

"stringa" <> "string [255]" <> "ShortString" <> AnsiString

Indietro nei vecchi giorni DOS/Turbo Pascal, "stringhe" sono stati infatti limitati a 255 caratteri. In gran parte perché il 1 ° byte conteneva la lunghezza della stringa e un byte può avere solo un valore compreso tra 0 e 255.

Questo non è più un problema nelle versioni contemporanee di Delphi.

"ShortString" è il tipo per il vecchio tipo di stringa DOS/Pascal.

"LongString" è stato il tipo di stringa predefinito per un lungo periodo di tempo (incluso il Borland Delphi 2006 che attualmente utilizzo per la maggior parte del lavoro di produzione). Da Delphi 3 .. Delphi 2009, LongStrings conteneva caratteri a 8 bit ed erano limitati solo dalla memoria disponibile. Da Delphi 3 .. Delphi 2009, "LongStrings" erano sinonimi di "AnsiStrings".

Le versioni recenti di Delphi (Delphi 2009 e versioni successive, incluso il nuovo Delphi XE2) sono tutte predefinite per le stringhe Unicode "WideString" multibyte. WideStrings, come AnsiStrings, sono anche effettivamente "illimitate" in lunghezza massima.

Questo articolo spiega più in dettaglio:

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

PS: Considerare l'utilizzo di "sizeof (bbil)" e "Packed" per i record binari.

+1

Nella terminologia Delphi, le stringhe lunghe si riferiscono sia ad AnsiString che a UnicodeString, essendo quest'ultimo il nuovo tipo di stringa introdotto su D2009. E WideString è di nuovo diverso, è un wrapper attorno al BSTR COM. –

+2

@rseffner - La terminologia può essere fonte di confusione. Per lo più colpa di Microsoft. Si prega di guardare i link che ho citato (in particolare l'articolo "about.com") per capire le stringhe. E per favore prova con "sizeof()" per risolvere problemi di imballaggio e allineamento con i tuoi record binari. – paulsm4

+1

La terminologia è perfettamente chiara e nulla a che vedere con la SM. La lingua in questione è prodotta da Embarcadero. Il mio commento precedente stava cercando di orientarti verso la correzione dei vari errori nella tua risposta. Così com'è, è piuttosto impreciso. –

0

Forse sto trascurando qualcosa, ma, per come la vedo io, anche il tuo codice delphi 3 è rotto. Prova per determinare la dimensione del record:

bbil = record 
    path : string; 
    pos: byte; 
    nr: Word; 
end; 

percorso (nulla tra 1 e 256 - un byte per la lunghezza, riposo per i dati), pos (1 byte), nr (2 byte), rendendo i dati del record le dimensioni variano da 1 + 1 + 2 = 4 byte a 256 + 1 + 2 = 259 byte. In tale circostanza, si otterrebbe comunque la spazzatura dai file, dal momento che il programma non può ora quanti byte leggere, prima di leggere effettivamente i dati. Vi suggerisco di risolvere il record in modo che la stringa è di una dimensione fissa, come:

path : ShortString[255]; 

Poi, si sarebbe in grado di scrivere e leggere bene sia in Delphi 3 e il 2010.

+0

Quindi, ancora una volta, delphi 3 non ha il tipo di stringhe a pantalone, dovrai definirlo come stringa in delphi 3. –

Problemi correlati