Domanda

Ho appena ricevuto Delphi 2009 e in precedenza ho letto alcuni articoli sulle modifiche che potrebbero essere necessarie a causa del passaggio alle stringhe Unicode. Principalmente, si dice che sizeof (char) non è più garantito di essere 1. Ma perché sarebbe interessante riguardo alla manipolazione delle stringhe?

Ad esempio, se uso AnsiString: = 'Test' e faccio lo stesso con una stringa (che ora è unicode), ottengo Length () = 4 che è corretto per entrambi i casi. Senza averlo provato, sono sicuro che tutte le altre funzioni di manipolazione delle stringhe si comportano allo stesso modo e decidono internamente se l'argomento è una stringa unicode o qualcos'altro.

Perché la dimensione effettiva di un carattere potrebbe interessarmi se eseguo manipolazioni di stringhe? (Naturalmente se uso stringhe come stringhe e non per memorizzare altri dati)

Grazie per l'aiuto!   Holger

È stato utile?

Soluzione

Con Unicode SizeOf (SomeChar) < > Lunghezza (SomeChar) . In sostanza, la lunghezza di una stringa è inferiore alla somma della dimensione del suo carattere . Finché non supponi SizeOf (Char) = 1 o SizeOf (SomeString [x]) = 1 (poiché entrambi sono FALSE ora) o prova a scambiare byte con carattere , quindi non dovresti avere problemi. In qualsiasi posto in cui stai facendo qualcosa di creativo inserendo byte in Char so String , dovrai utilizzare AnsiString .

(SizeOf (SomeString) è ancora 4, non importa la lunghezza poiché è essenzialmente un puntatore con qualche magia del compilatore.)

Altri suggerimenti

Le persone spesso convertono implicitamente da caratteri a byte nel vecchio codice Delphi senza pensarci davvero. Ad esempio, quando si scrive su uno stream. Quando scrivi una stringa in uno stream, devi specificare il numero di byte che scrivi, ma le persone spesso passano il conteggio dei caratteri. Vedi questo post di Chris Bensen per un altro esempio.

Un altro modo in cui le persone spesso fanno questa conversione implicita e il codice più vecchio è usando una " string " per archiviare dati binari. In questo caso, in realtà vogliono byte, ma il tipo di dati prevede caratteri. D2009 ha un tipo migliore per questo .

Non ho provato Delphi 2009, ma sto usando fpc che sta anche passando lentamente all'unicode. Sono sicuro al 95% che tutto quanto segue vale anche per Delphi 2009

In fpc (quando supporta unicode) sarà così che funzioni come 'lunghezza' prendono in considerazione la tabella codici. Quindi restituirà la lunghezza della stringa come la vedrebbe un 'umano'. Se ci sono - per esempio - due caratteri cinesi, che occupano entrambi due byte di memoria in unicode, la lunghezza restituirà 2, poiché ci sono due caratteri nella stringa. Ma la stringa richiederà 4 byte di memoria. (+ la memoria per il conteggio dei riferimenti e il # 0 iniziale, ma a parte questo)

Quello che non puoi più fare è questo:

var p : pchar;
begin
  p := s[1];
  for i := 0 to length(string)-1 do
    begin
    write(p);
    inc(p);
    end;      
end;

Perché questo codice - nell'esempio di due caratteri cinesi - scriverà i due caratteri sbagliati. Vale a dire i due byte che fanno parte del primo carattere "reale".

In breve: Length () non restituisce più la quantità di byte allocati per la stringa, ma la quantità di caratteri. (Prima del passaggio all'unicode, quei due valori erano uguali tra loro)

Le dimensioni effettive di un personaggio non dovrebbero avere importanza, a meno che non si stia manipolando a livello di byte.

  

(Naturalmente se uso stringhe come stringhe e non per memorizzare altri dati)

Questo è il punto chiave, TU non usi le stringhe per altri scopi, ma alcune persone lo fanno. Usano le stringhe proprio come gli array, quindi (e questo include me) dovrebbero controllare tutti questi usi per assicurarsi che nulla sia rotto ...

Non dimentichiamo che ci sono momenti in cui questa conversione non è davvero desiderata. Ad esempio, per la memorizzazione di un GUID in un record. Il guid può contenere solo caratteri esadecimali più il - e le parentesi ... facendoli occupare il doppio dello spazio può avere un impatto notevole sul codice esistente. Sicuramente la soluzione semplice è cambiarli in AnsiString e gestire gli avvisi del compilatore se si esegue una manipolazione delle stringhe su di essi.

Può essere un problema se si effettuano chiamate API Windows. Oppure se hai un codice legacy che inc o dec di str [0] per cambiarne la lunghezza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top