Domanda

Stavo ottenendo il consiglio di Rob Kennedy e uno dei suoi suggerimenti che aumentavano notevolmente la velocità di un'app su cui stavo lavorando era di usare SetString e quindi caricarlo nel componente VCL che veniva visualizzato esso.

Sto usando Delphi 2009, quindi ora PChar è Unicode,

SetString(OutputString, PChar(Output), OutputLength.Value);
edtString.Text := edtString.Text + OutputString;

Funziona e l'ho cambiato in PChar da solo, ma poiché i dati che vengono spostati non sono sempre Unicode, in realtà sono solitamente i dati ShortString .... quindi su ciò che mi ha effettivamente dato da usare:

SetString(OutputString, PAnsiChar(Output), OutputLength.Value);
edtString.Text := edtString.Text + OutputString;

Non viene visualizzato nulla, ma controllo il debugger e il testo che normalmente appariva nel modo in cui l'ho fatto costruendo 1 carattere alla volta in passato era nella variabile.

Stranamente non è la prima volta che mi imbatto in questa sera. Dato che stavo cercando di trovare un altro modo, ho preso parte dei suoi consigli e invece di inserirmi nella TCaption di un VCL l'ho costruito in una variabile stringa e poi l'ho copiato, ma quando lo invio su nulla viene visualizzato. Ancora una volta nel debugger la variabile in cui sono integrati i dati ... ha i dati.

for I := 0 to OutputLength.Value - 1 do
begin
  OutputString := OutputString + Char(OutputData^[I]);
end;
edtString.Text := OutputString;

Quanto sopra non funziona ma il vecchio modo lento di farlo ha funzionato bene ....

for I := 0 to OutputLength.Value - 1 do
begin
  edtString.Text := edtString.Text + Char(OutputData^[I]);
end;

Ho provato a rendere la variabile ShortString, String e TCaption e non viene visualizzato nulla. Quello che trovo anche interessante è che mentre io costruisco i miei dati esadecimali dallo stesso array in un richedit è molto veloce mentre farlo all'interno di una modifica per i dati di testo è molto lento. Questo è il motivo per cui non mi sono preoccupato di provare a cambiare il codice per il richedit in quanto funziona superveloce come è.

Modifica per aggiungere - Penso di aver trovato il problema ma non ho soluzione. Se modifico il valore nel debugger per rimuovere tutto ciò che non può essere visualizzato (che con il vecchio metodo usato per non visualizzare ... non fallire), viene visualizzato ciò che mi rimane. Quindi, se si tratta solo di eliminare i byte che sono stati trasformati in caratteri che sono spazzatura, come posso risolvere il problema?

Fondamentalmente ho dati grezzi in arrivo da un dispositivo SCSI che viene visualizzato in stile hex-editor. Il mio stile lento originale di aggiungere un carattere alla volta mostrava con successo stringhe e stringhe Unicode che non contenevano caratteri specifici Unicode. I metodi più veloci anche se funzionanti non visualizzeranno ShortStrings in un modo e nell'altro modo non visualizzeranno UnicodeStrings che non utilizzano caratteri non 0-255. Mi piace molto e potrei usare l'aumento di velocità, ma se ciò significa sacrificare la capacità di leggere la stringa ... allora qual è il punto nell'app?

EDIT3 - Bene ora che ho capito che 0-31 è control char e 32 e up è valido Penso che proverò a filtrare char e sostituire quelli non validi con a. che è qualcosa che stavo pianificando di fare in seguito per emulare lo stile dell'editor esadecimale.

Se ci sono altri suggerimenti, sarei felice di sentirli, ma altrimenti penso di poter realizzare una soluzione più veloce dell'originale e fare ciò di cui ho bisogno allo stesso tempo.

È stato utile?

Soluzione

Ho usato PAnsiChar nel mio esempio per un motivo. Sembrava che OutputLength fosse misurato in byte, non in caratteri, quindi mi sono assicurato di usare un tipo la cui lunghezza è sempre misurata in byte. Noterai anche che ho mostrato la dichiarazione di OutputString come AnsiString .

Poiché il controllo di modifica ha archiviato Unicode, tuttavia, ci sarà una conversione tra AnsiString e UnicodeString . Ciò terrà conto della tabella codici corrente del sistema, ma probabilmente non è quello che vuoi. In alternativa, potresti voler dichiarare la variabile come RawByteString . Che non avrà alcuna tabella codici associata, quindi non ci saranno conversioni impreviste.

Non utilizzare stringhe per la memorizzazione di dati binari. Se stai creando ciò che equivale a un editor esadecimale, stai lavorando con dati binari. È importante ricordarlo. Anche se i tuoi dati binari accade consistono principalmente di byte che possono essere interpretati come testo, non puoi trattare i dati come testo o incontrerai esattamente i problemi che stai vedendo - caratteri che non apparire come previsto. Se ricevi un sacco di byte dal tuo dispositivo SCSI, quindi memorizzali in una matrice di byte, non in caratteri.

Negli editor esadecimali, noterai che mostrano sempre i valori esadecimali dei byte. Potrebbero mostrare quei byte interpretati come caratteri, ma questo è secondario e generalmente mostrano solo i byte che possono rappresentare caratteri ASCII; non cercano di essere troppo fantasiosi con il display di base. Gli editor esadecimali buoni offriranno anche di visualizzare i dati interpretati come caratteri ampi. Questo aiuta nel debug perché l'utente può guardare gli stessi dati in più modi. Ma sono solo visualizzazioni dei dati. In realtà non stanno modificando il contenuto binario dei dati.

Altri suggerimenti

Alcuni commenti:

  1. La tua domanda non è chiara. Che cosa vuoi fare esattamente?
  2. La tua domanda è terribile, controlla il tuo testo con un correttore ortografico.
  3. La domanda a cui ti stai riferendo è questa: Delphi che accede ai dati dall'array dinamico popolato da un puntatore non tipizzato
  4. Fornisci un esempio di codice completo della tua funzione come hai fatto nella tua domanda precedente, voglio sapere se hai implementato il suggerimento di Rob Kennedy o il codice che ti sei dato in una risposta seguente (speriamo di no :))
  5. Per quanto ho capito la tua domanda: stai inviando una query al tuo dispositivo SCSI e ottieni una matrice di byte che memorizzi nella variabile OutputData. Successivamente, desideri mostrare i tuoi dati all'utente. Quindi la tua vera domanda è: Come mostrare una matrice di byte all'utente?
  6. Accedi come lo stesso utente e non creare un account per ogni nuova domanda. In questo modo possiamo tracciare la cronologia delle tue domande e scoprire cosa intendi per "ottenere consigli".

Alcuni presupposti e suggerimenti se ho ragione sul vero significato della tua domanda:

  1. Mostrare i tuoi dati come una stringa esadecimale non darà alcun problema
  2. Mostrare i tuoi dati in un normale campo Memo ti dà problemi, anche se una stringa Delphi può contenere qualsiasi carattere, inclusi 0 byte, visualizzarli ti darà problemi. Un TMemo per esempio mostrerà i tuoi dati fino al primo 0 byte. Quello che devi fare (e hai dato tu stesso la risposta), è sostituire i personaggi non visualizzabili con un manichino. Successivamente puoi mostrare i tuoi dati in un TMemo. In realtà tutti i visualizzatori esadecimali fanno lo stesso, i caratteri che non possono essere stampati verranno visualizzati come un punto.

Quando filtri i caratteri non visualizzabili ... Probabilmente dovrai decidere cosa fare con un paio di loro come # 9 (Tab), # 10 (LF), # 11 (Scheda Verticle), # 12 (FF-o nuova pagina), # 13 (CR)

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