|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jul 2003
Messaggi: 280
|
[C]mettere int in vettore unsigned char come hex
sto scrivendo una applicazione client-server.
le comunicazioni tra i due avvengono inviando "messaggi" composti da un vettore di unsigned char che vengono tutti interpretati o come serie di caratteri ( se vine inviato/ricevuto una stringa) oppure come dei valori interi,ma ho questo problema : ----------------- int intero=3106; unsigned char caratteri[20]; caratteri[5]=intero; ----------------- che come capite NON funziona,perche' (dec)3106 = (hex)C22 e ovviamente C22 NON ci sta in un solo unsigned char dovrei fare : caratteri[5]=0x0C caratteri[6]=0x22 inoltre dato che devo inviare questi dati via tcp mi vedo costretto a doverli invertirli quindi : caratteri[5]=0x22 caratteri[6]=0x0C avete suggerimenti per risolvere questo problema ? |
![]() |
![]() |
![]() |
#2 | |
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Re: [C]mettere int in vettore unsigned char come hex
Quote:
![]() |
|
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Jul 2003
Messaggi: 280
|
forse sto facendo un macello e non sono stato molto chiaro .
dunque ho un vettore di unsigned char : unsigned char messaggio[20]; questo vettore lo "riempio" per esempio con dei caratteri: messaggio[0]='c'; messaggio[1]='i'; messaggio[2]='a'; messaggio[3]='o'; oppure con dei valori in esadecimale (hex): messaggio[4]=0x01; messaggio[5]=0x02; messaggio[6]=0xAA; ora vorrei mettere in messaggio[7] il valore intero in base 10 3106 : int intero = 3106;//OK messaggio[7]=intero; //QUESTA COSA NON FUNZIONA !!! ed e' giusto che non funzioni, perche' il valore massimo che posso mettere in un unsigned char e' 0xFF , cioe' 255 . 3106 in esadecimale e' : C22 in pratica devo utilizzare sia messaggio[7] sia messaggio[8],cioe': messaggio[7]=0x0C; messaggio[8]=0x22; |
![]() |
![]() |
![]() |
#4 | |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
Quote:
La cosa piu' semplice e' fare un cast dell'array ad un array di interi e poi scriverci direttamente. Se pero' devi mandare il messaggio su architetture differenti, ti conviene convertire il valore in un formato neutrale, e fissare il numero di bit che vuoi usare Ad esempio, se ti bastano gli interi senza segno puoi fare qualcosa del genere (notazione C++, per il C ci potrebbero essere delle differenze minori): Codice:
#include <netinet/in.h> ... uint32_t* x = (uint32_t*) messaggio; x[0]=htonl(3106); // questo va a scrivere da messaggio[0] a messaggio[3] Codice:
#include <netinet/in.h> ... uint32_t* x = (uint32_t*) messaggio; uint32_t n = ntohl( x[0] ); DISCLAIMER: codice non testato, pensato per un S.O. che potrebbe non essere il tuo, in ogni caso prima di provarlo fai un backup ![]() ![]() |
|
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Quote:
Devi modificare il tuo programma e dichiarare messaggio[20] come vettore di unsigned int e non di unsigned char. Un unsigned char può variare da 0 a 255. Se vuoi un valore superiore devi orientarti su altri tipi di dato.... ;-) |
|
![]() |
![]() |
![]() |
#6 | |
Member
Iscritto dal: Jul 2003
Messaggi: 280
|
Quote:
PS: il tipo di dati non lo posso cambiare se no lo avrei gia' fatto, mannaggia la miseriaccia LOL !!! PS2:cmq ora provo a smazzare il cast come indicato sopra. grazie gente. |
|
![]() |
![]() |
![]() |
#7 | |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
Quote:
![]() ![]() Su una macchina a 32 bit un intero e' solitamente di 32 bit, quindi 4 byte, era di 2 byte nelle architetture a 16 bit (o su macchine a 32 bit che eseguono codice a 16 bit ) |
|
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Quote:
* char -128 to +127 8bit * unsigned char 0 to +255 8bit * short -32768 to +32767 16bit * unsigned short 0 to +65535 16bit * long -2 147 483 648 to +2 147 483 647 32bit * unsigned long 0 to +4 294 967 295 32bit * int -32768 to +32767 16bit or * int -2 147 483 648 to +2 147 483 647 32bit * unsigned int 0 to +65535 16bit or * unsigned int 0 to +4 294 967 295 32bit * float ??? 32bit * double ??? 64bit * long double ??? 80bit or * long double ??? 64bit Che tu compili un programma per farlo girare su un pentium, su un PIC16F86 su un ATMEL, su un ARM, su un Itanium o su un TI sono comunque cazzi del compilatore quelli di utilizzare i registri che quel dato processare ha per poter memorizzare certi tipi di dato, ma i tipi di dato sono questi. Li trovi su qualsiasi libro di C!!! Probabilmente fai casino con l'architettura dei processori, ma il linguaggio C è tutt'altra cosa. Ultima modifica di fantoibed : 28-12-2004 alle 18:43. |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Quote:
Che genere di programma stai scrivendo? Se posti un po' di codice in più provo a vedere cosa riesco a farci... ![]() |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Jul 2004
Messaggi: 1578
|
Non so cosa ci devi poi fare con quel vettore, ma non sarebbe più semplice assegnare più di uno slot per ogni dato?
Per esempio, assegnando due slot (char) potresti distinguere 2^16 configurazioni invece che 2^8 semplicemente mettendo nel primo le due cifre esadecimali più significative, nel secondo le due meno significative. Magari una soluzione del genere potrebbe esserti più utile se non vuoi modificare troppo il tuo codice. |
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Quote:
Codice PHP:
|
|
![]() |
![]() |
![]() |
#12 |
Member
Iscritto dal: Jul 2003
Messaggi: 280
|
allora via "cast" nulla da fare a parte un warning su gcc ( visual manco se ne accorge ...)
la soluzione "parziale e incompleta " che ho trovato e' usare lo shift come segue : packet_info[19]=(unsigned char)1233; packet_info[20]=(unsigned char)1233>>8; dovrei trovare ora una funzione che mi dica 34 e' grosso 1 byte; 1233 e' grosso 2 byte; K e' grosso N byte poi faccio un for del tipo: // X e' la posizione del vattore da cui partire a scrivere il valore intero for (i=0;i<N;i++) { vettore[ i + x]= valore_intero >> ( 8 * i ) ; } che ne dite ? |
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
Qui ti sbagli . Ogni architettatura ha la sua dimensione tipo di INT . Su un sistema a 32bit la dimensione di un INT in C è 32bit ,ossia 4 bytes , su un 286 erano 16bits ossia 2 bytes . Mi sembra che sei te ches tai facendo un po' di confusione . Anche perchè avrebbe poco senso su un sistema a 64 bit usare ancora int a 16 bit o "long int" a 32bit , non ti sembra? Ciao
__________________
GPU Compiler Engineer |
|
![]() |
![]() |
![]() |
#14 | |||
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Quote:
![]() Quote:
Il fatto che il 34 si riesca a far stare in un byte mentre 1233 no, è un'altra cosa. Puoi implementare un controllino del tipo: Codice PHP:
Quote:
![]() Potevo già farti il caso generico di N bytes. Vabbè, la prossima volta. Ma, per curiosità, che programma è? Cosa dovrebbe fare e a cosa dovrebbe servire? |
|||
![]() |
![]() |
![]() |
#15 | |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
Quote:
L'unica costante quasi universale e' la dimensione di 8 bit per un char. Non ho sottomano un manuale C, ma su quello C++ (e su queste cose in linea di massima i due linguaggi coincidono), presa come costante 'sizeof(char)==1' valgono le seguenti relazioni 1 = sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) 1 <= sizeof(bool) <= sizeof(long) sizeof(float) <= sizeof(double) <= sizeof(long double) Inoltre un char deve essere di almeno0 8 bit, uno short di almeno 16, e un intero di almeno 32bit |
|
![]() |
![]() |
![]() |
#16 | ||
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
Quote:
Quote:
Ti conviene partire dal presupposto che lavori sempre con interi da 32 bit (ad esempio) e salvi sempre tutti e 4 i byte. |
||
![]() |
![]() |
![]() |
#17 | |||
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Quote:
![]() Quote:
Quote:
Eppure esistono short int e long int rispettivamente a 16bit e 32bit sia sui 286 che sui Pentium... Per i 64bit, invece, hanno inventato i long long int, ma allora un int su un Athlon64 equivale ad un long long ? Mah! Ultima modifica di fantoibed : 02-01-2005 alle 19:52. |
|||
![]() |
![]() |
![]() |
#18 | |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
Quote:
e' un long che e' almeno 32 bit |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:30.