View Full Version : [C++] creare un array unsigned char concatenato
DomusP45
29-03-2012, 17:58
Salve a tutti.
Vi posto questa domanda più specifica di come è stata trattata da altre parti, con la speranza che qualcuno mi sappia aiutare.
Come si fa il concatenamento di array "unsigned char"??
Non è possibile farlo con strcat, perchè non sono caratteri, ma debbono rimanere byte...quindi non mi dite di fare stringhe di caratteri o altro, perchè si perde il valore di quello che contiene il vettore, cioè bit.
Nè penso si possa usare un casting, perchè complica le cose dopo nel ritornare unsigned, tipo come mi è stato detto da un'altra parte fare una strcat((char*)vett1,(char*)vett2) dove vett1 e vett2 sono unsigned.
Vi spiego con un esempio di cosa ho e cosa voglio: Devo inviare un buffer unsigned char da 8 byte. Però devo ottenerlo da diversi piccoli array sempre unsigned. In pratica, ad esempio ho:
unsigned char DLEN[1]={0x01};
unsigned char CMD[1]={0x05};
unsigned char DATA[4]={0x00,0x92,0x4f,0x81}
unsigned char CRC[2]={0x92,0x31}
e devo ottenere
unsigned char buffer[8]={0x01,0x05,0x00,0x92,0x4f,0x81,0x92,0x31}
E' così che deve essere il risultato.
Come si fa? Come è possibile ottenere una cosa del genere??Aiutatemi!
ESSE-EFFE
29-03-2012, 19:44
unsigned char DLEN[1]={0x01};
unsigned char CMD[1]={0x05};
unsigned char DATA[4]={0x00,0x92,0x4f,0x81}
unsigned char CRC[2]={0x92,0x31}
e devo ottenere
unsigned char buffer[8]={0x01,0x05,0x00,0x92,0x4f,0x81,0x92,0x31}
Quello che ti hanno suggerito non è sbagliato, nel senso che sia una stringa o un array, signed o unsigned, il valore dei byte non cambia. Tuttavia considerarli stringhe non ha molto senso e potresti avere problemi col terminatore nullo.
Copia semplicemente i vari array nell'array finale, o assegnando direttamente il valore (buffer[0] = DLEN[0]) oppure tramite memcpy, campo per campo, tenendo traccia di dove stai copiando tramite un puntatore (puoi farti una funzione per generalizzare la cosa ovviamente).
Ancora meglio sarebbe tenere i 4 campi in una struttura (allineata al byte). In quel modo ti basta una memcpy e la cosa risulta decisamente più elegante.
__ZERO_UNO__
29-03-2012, 20:55
Come ti ha suggerito ESSE-EFFE, bit fields: http://msdn.microsoft.com/en-us/library/ewwyfdbe%28v=vs.71%29.aspx
Comunque se fai il cast utilizzando static_cast non cambiano i bit ma solo l'interpretazione.
ESSE-EFFE
29-03-2012, 20:58
Come ti ha suggerito ESSE-EFFE, bit fields: http://msdn.microsoft.com/en-us/library/ewwyfdbe%28v=vs.71%29.aspx
No, scusami, ma io non ho suggerito i bit fields. Anche perchè non è quello che serve all'OP.
__ZERO_UNO__
29-03-2012, 21:00
Ho travisato l'uso della struttura. :P
Però se mette i quattro unsigned char in un int dentro una struttura ottiene una singola word con tutti i bit configurati come vuole.
Ah già, lui vuole un unsigned char .....
DomusP45
29-03-2012, 21:39
Ok, penso di aver capito l'antifona...devo fare delle prove....ed il bello è, che alcuni di questi unsigned char devono essere immessi da tastiera da un probabile utente, pertanto, come mi consigliate di farglieli acquisire?
Nel senso: messo che devo far mettere al mio utente 4 di quei bit, avevo pensato a cin.getline, però non so se ottengo quello che mi serve, l'utente dovrebbe inserirli con lo spazio, o con la virgola tra loro?
Che tipo uso per l'introduzione? Cosa gli faccio acqusire un int e poi lo devo trasformare in esadecimale? (quei 4 bit dovrebbero rappresentare una posizione in mm o una corrente in mA) Oppure devo fargli introdurre direttamente un unsigned char pezzo a pezzo (4 volte quindi).
ESSE-EFFE
30-03-2012, 09:15
Nel senso: messo che devo far mettere al mio utente 4 di quei bit, avevo pensato a cin.getline, però non so se ottengo quello che mi serve, l'utente dovrebbe inserirli con lo spazio, o con la virgola tra loro?
Non sono bit, sono byte. Non complicherei la cosa: se servono 4 dati farai inserire 4 dati, senza virgole o sintassi particolari.
Che tipo uso per l'introduzione? Cosa gli faccio acqusire un int e poi lo devo trasformare in esadecimale? (quei 4 bit dovrebbero rappresentare una posizione in mm o una corrente in mA) Oppure devo fargli introdurre direttamente un unsigned char pezzo a pezzo (4 volte quindi).
L'immissione non può che avvenire tramite caratteri ASCII. Vista la natura di quei valori, dei numeri decimali mi sembrano appropriati, cioè se devono essere 234 mA direi che è opportuno che l'utente inserisca proprio "234". E poi ti basta convertire in intero e memorizzare il dato nella posizione corretta dell'array.
DomusP45
30-03-2012, 10:04
Non sono bit, sono byte. Non complicherei la cosa: se servono 4 dati farai inserire 4 dati, senza virgole o sintassi particolari.
Quindi gli dico qualcosa come immetti il primo valore: , ENTER, Immetti il secondo valore: " ecc...oppure
"Immetti i parametri : " e l'utente scrive "00 00 41 22" ?
L'immissione non può che avvenire tramite caratteri ASCII. Vista la natura di quei valori, dei numeri decimali mi sembrano appropriati, cioè se devono essere 234 mA direi che è opportuno che l'utente inserisca proprio "234". E poi ti basta convertire in intero e memorizzare il dato nella posizione corretta dell'array.
Mmmm...sai cos'è che questi benedetti 4 bit non sono poi l'equivalente del valore in esadecimale, ma anche qualcos'altro. Ho chiesto delucidazioni alla casa madre della pinza, e resto in attesa che mi facciano sapere...certo è che facendo le conversioni (con alcuni esempi che portano sul manuale) non mi trovo proprio con i valori...questi 4 bit potrebbero essere anche indicativi di altro, tipo velocità, corrente, tipo di movimento...e quindi su questo ho ancora il dubbio.
Quello che non mi è chiaro è: ma se all'utente è chiesto di immettere un valore, e l'utente immette "12" (immissione classica cin>>i , con i di tipo int) quando vado a copiarlo nella posizione "tot" dell'array unsigned char, il compilatore in fase di runtime converte automaticamente il valore in byte? Nella sua rappresentazione esadecimale? Cioè mi ritroverò dentro all'array il valore "0C"? Perchè è sta cosa che non capisco bene...
ESSE-EFFE
30-03-2012, 10:10
Quindi gli dico qualcosa come immetti il primo valore: , ENTER, Immetti il secondo valore: " ecc...oppure
"Immetti i parametri : " e l'utente scrive "00 00 41 22" ?
Supponi che sia tu ad immetterli... come preferiresti farlo? Ecco, dai all'utente la stessa possibilità.
Mmmm...sai cos'è che questi benedetti 4 bit non sono poi l'equivalente del valore in esadecimale, ma anche qualcos'altro.
Sono byte, non bit. Ma comunque questo fa parte del protocollo, non c'entra con l'input. Prendi i dati dall'utente e adattali di conseguenza.
Quello che non mi è chiaro è: ma se all'utente è chiesto di immettere un valore, e l'utente immette "12" (immissione classica cin>>i , con i di tipo int) quando vado a copiarlo nella posizione "tot" dell'array unsigned char, il compilatore in fase di runtime converte automaticamente il valore in byte? Nella sua rappresentazione esadecimale? Cioè mi ritroverò dentro all'array il valore "0C"? Perchè è sta cosa che non capisco bene...
Ovviamente servirà una conversione da ASCII ad intero. Poi dire che in memoria c'è 12 o 0x0C è la stessa cosa, cambia la rappresentazione. Se non ti è chiaro, fai qualche prova.
ti mancano proprio le basi :)
comunque
1) mai usare cin per acquisire un intero se per sbaglio l'utente preme una lettera il programma crasha
2)acquisisci una stringa di testo con cin.getline, la converti in un intero con atoi mentre per scriverla in esadecimale nel vettore usa sprintf, se invece lavori su un output (es file o file di periferica) puoi usare tranquillamente hex
ESSE-EFFE
30-03-2012, 10:19
2)acquisisci una stringa di testo con cin.getline, la converti in un intero con atoi mentre per scriverla in esadecimale nel vettore usa sprintf
Non deve convertire il dato in esadecimale per scriverlo nel vettore.
DomusP45
30-03-2012, 10:25
a me mancheranno anche le basi, ma a quanto pare non c'è accordo su questa cosa.
Anche perchè sprintf io l'ho usata e con l'unsigned char non ci vuole avere a che fare...insomma, mi creava all'interno del vettore simboli strani...eppure mi sono visto la guida reference su sito cplusplus, è un'ottima funzione per l'output, personalizzabile persino quante cifre prima e dopo lo zero, però è per stringhe, caratteri...qua invece devono essere byte.
Qualcuno mi dice una volta per tutte in modo chiaro, se devo convertire l'intero acquisito prima di immetterlo nel vettore, oppure posso fare direttamente l'assegnazione e ritrovarmelo (quando vado ad inviarlo alla porta seriale) nel formato corretto?
ESSE-EFFE
30-03-2012, 10:31
Qualcuno mi dice una volta per tutte in modo chiaro, se devo convertire l'intero acquisito prima di immetterlo nel vettore, oppure posso fare direttamente l'assegnazione e ritrovarmelo (quando vado ad inviarlo alla porta seriale) nel formato corretto?
Non lo devi convertire. Vuoi toglierti il dubbio? Prova...
DomusP45
30-03-2012, 10:34
Non lo devi convertire. Vuoi toglierti il dubbio? Prova...
grazie mille esse-effe. Tra poco prendo il treno e parto, sarò in laboratorio per le 12...e faccio tutte le prove del caso...se non ho problemi, probabilmente avrò risolto una parte delle cose, con questo sistema...altrimenti, ti contatto! :D
buona giornata!!
ESSE-EFFE
30-03-2012, 10:39
Tra poco prendo il treno e parto, sarò in laboratorio per le 12...e faccio tutte le prove del caso...
Cioè per provare a scrivere un numero in un array devi prendere il treno? :eek:
DomusP45
30-03-2012, 12:39
Cioè per provare a scrivere un numero in un array devi prendere il treno? :eek:
Viaggio per andare in laboratorio...tutto il materiale sta nel pc in laboratorio...poi devo provare con la pinza o no?
Al volo al volo, mi dici una cosa? Come faccio la conversione da unsigned char a float? Il casting per avere a video il valore in float di un array unsigned char come si fa??
ESSE-EFFE
30-03-2012, 13:17
Viaggio per andare in laboratorio...tutto il materiale sta nel pc in laboratorio...poi devo provare con la pinza o no?
Per provare quello di cui non eri sicuro la pinza non serve, neanche volendo testare l'invio seriale...
Come faccio la conversione da unsigned char a float? Il casting per avere a video il valore in float di un array unsigned char come si fa??
Il valore "float" di un "unsigned char" è ancora lo stesso valore.
DomusP45
30-03-2012, 13:22
Il valore "float" di un "unsigned char" è ancora lo stesso valore.
OK, nella pratica, devo verificare se questo array è un float, nel senso che devo sapere quanto vale:
unsigned char dat[]={0x00 ,0x00 ,0x20 ,0x41}
dovrebbe corrispondere all'invio di "posizione 10 mm" come faccio a vedere se corrisponde a 10 (mm) oppure a 10x10-3 (ad esempio)?
ESSE-EFFE
30-03-2012, 13:42
OK, nella pratica, devo verificare se questo array è un float, nel senso che devo sapere quanto vale:
unsigned char dat[]={0x00 ,0x00 ,0x20 ,0x41}
dovrebbe corrispondere all'invio di "posizione 10 mm" come faccio a vedere se corrisponde a 10 (mm) oppure a 10x10-3 (ad esempio)?
Questo però mi sembra un problema che non ha nulla a che vedere con il discorso iniziale.
Viaggio per andare in laboratorio...tutto il materiale sta nel pc in laboratorio...poi devo provare con la pinza o no?
Al volo al volo, mi dici una cosa? Come faccio la conversione da unsigned char a float? Il casting per avere a video il valore in float di un array unsigned char come si fa??
Cosa intendi di preciso?
Partiamo dalla teoria:
Dimensioni dei tipi (dando per buona l'architettura a 32bit):
char 8 bit 1 byte
int 32 bit 4 bytes
long long 64 bit 8 bytes
float 32 bit 4 bytes
double 64 bit 8 bytes
Ciò significa che in ogni istante puoi vedere un numero intero (ad esempio) come una sequenza di 4 bytes, in un dato ordine.
Ciò significa anche che questi 4 bytes possono essere interpretati come float.
Tutto dipende da come dici tu di leggere quella sequenza di byte:
unsigned char Buffer[] = { 0x00, 0x00, 0x01, 0x01 };
float* F = (float*) Buffer;
int* I = (int*) Buffer;
printf("Buffer float %f\n", *F);
printf("Buffer int %d\n", *I);
Sempre che questo sia quello che vuoi fare.
Altrimenti basta un semplice cast, ma ottieni lo stesso valore, come diceva ESSE-EFFE.
DomusP45
30-03-2012, 13:54
Questo però mi sembra un problema che non ha nulla a che vedere con il discorso iniziale.
E' un'altra domanda che ti ho fatto...fa parte dei parametri che possono essere inviati.
Allora?
DomusP45
30-03-2012, 14:00
Cosa intendi di preciso?
Partiamo dalla teoria:
Dimensioni dei tipi (dando per buona l'architettura a 32bit):
char 8 bit 1 byte
int 32 bit 4 bytes
long long 64 bit 8 bytes
float 32 bit 4 bytes
double 64 bit 8 bytes
Ciò significa che in ogni istante puoi vedere un numero intero (ad esempio) come una sequenza di 4 bytes, in un dato ordine.
Ciò significa anche che questi 4 bytes possono essere interpretati come float.
Tutto dipende da come dici tu di leggere quella sequenza di byte:
unsigned char Buffer[] = { 0x00, 0x00, 0x01, 0x01 };
float* F = (float*) Buffer;
int* I = (int*) Buffer;
printf("Buffer float %f\n", F);
printf("Buffer int %d\n", I);
Sempre che questo sia quello che vuoi fare.
Altrimenti basta un semplice cast, ma ottieni lo stesso valore, come diceva ESSE-EFFE.
Grazie...si, l'idea è quella...infatti il casting così l'ho fatto...
anche se non restituisce i valori che mi aspetto, nel qual caso non restituisce nè 10 nè qualcosa che possa sembrare 10 alla meno qualcosa...quindi devo capire cosa è.
Viene fuori:
Buffer float 0.000000
Buffer int -1081905996
ESSE-EFFE
30-03-2012, 14:20
printf("Buffer float %f\n", *F);
Credo che i puntatori siano da derefereziare.
ESSE-EFFE
30-03-2012, 14:22
E' un'altra domanda che ti ho fatto...fa parte dei parametri che possono essere inviati.
Sì e quindi ora tutti i problemi che avrai li posterai in questo thread?
Allora?
Apri un thread apposito.
DomusP45
30-03-2012, 14:25
Credo che i puntatori siano da derefereziare.
grazie mille!
Credo che i puntatori siano da derefereziare.
Hai ragione, correggo :D.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.