Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Trasformare byte array in char
Forum - C/C++ - Trasformare byte array in char

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
mano17 (Normal User)
Newbie


Messaggi: 1
Iscritto: 17/01/2021

Segnala al moderatore
Postato alle 11:53
Domenica, 17/01/2021
Ciao tutti, è da poco che mi sono approciato agli array e mi trovo a dover mettere in un unico array char il contenuto di due array bidimensionali di tipo byte.
Ho scritto questo:

Codice sorgente - presumibilmente C#

  1. byte A1[3][5];
  2. byte A2[2][7];
  3. byte indice=0;
  4. char buffer_A[90];
  5. for (byte i=0;i<3;i++){for(byte c=0;c<5;c++){forma(A1[i][c]);indice=indice+2;}
  6.                        }
  7. for (byte a=0;a<2;a++){for(byte b=0;b<7;b++){forma(A2[a][b]);indice=indice+2;}
  8.                        }
  9. void forma(byte X){        //per convertire byte in char
  10.  
  11.        #define N 2
  12.      char a[N];
  13.           itoa(X,a,10);  //converto il numero byte X in char
  14.      byte l1 = strlen (a);
  15.           memmove (a + (N - l1), a, l1);
  16.           memset (a, '0', N - l1);    //riempio di 0 i vuoti
  17.           for (byte i=0;i<N;i++){buffer_A[indice+i+1]=a[i];
  18. }


Praticamente la funzione forma serve per mettere lo 0 davanti alle unità nel caso in qui il numero che gli passo è <10.
Il frame finale dovrà essere composto da valori in char dei numeri contenuti negli array, e se inferiori a 9 dovrò scrivere 09, in modo da mantenere sempre lo spazio di due cifre.
Gli array non conterranno mai numeri superiori a 70.
Se lancio un solo array funziona correttamente, ma se lancio entrambi gli arrai, oltre a non scrivere correttamente nel buffer_A, si impalla il micro...
Cosa sbaglio?
Qualche consiglio?
Grazie.

Ultima modifica effettuata da mano17 il 17/01/2021 alle 11:54
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 15:08
Domenica, 17/01/2021
Per rispondere dovrei provare il codice sembra C++, confermi?
Puoi postare un codice con gli array inizializzati e provabile?
Ci dici con quale IDE usi il codice?
lo puoi testare prima di metterlo nel micro?

byte e char sono la stessa cosa accupano un byte, per avere i numeri in formato carrattere con lo zero avanti ci vogliono 2 char oppure puoi usare string

Farebbe comodo se posti due array A1 e A2 d'esempio e come ti aspetti che siano collocati in buffer_A

Ultima modifica effettuata da Carlo il 17/01/2021 alle 15:22


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 699
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 18:11
Domenica, 17/01/2021
Secondo me sarebbe più pratico se impostassi diversamente la funzione forma(), passandole non solo il valore numerico, ma anche l'indirizzo nel quale scrivere le due cifre.

void forma(byte X, char* s);

A quel punto dalla funzione chiamante potresti passare come stringa di destinazione il puntatore al buffer incrementato dell'indice:

forma(A1[r][c], buffer_A+indice);

(Ho usato r e c per una mia abitudine a considerare le due coordinate una "riga" e una "colonna", ma è ovviamente irrilevante il nome che dai ai contatori.)

Così facendo saresti sicuro che le cifre vengano scritte nel posto giusto.

Una cosa mi lascia perplesso... ipotizzando che i valori nella prima matrice siano...

Codice sorgente - presumibilmente Plain Text

  1. // gli spazi li ho inseriti solo
  2. // per incolonnare le celle
  3. [ 1][ 2][ 3][ 4][ 5]
  4. [11][12][13][14][15]
  5. [21][22][23][24][25]



... buffer_A finirebbe per contenere 010203040511121314152122232425, cioè tutti i numeri "appiccicati" e praticamente illeggibili: è nelle tue intenzioni? In caso contrario occorre aggiungere tra l'uno e l'altro un separatore di un qualche tipo, ad esempio uno spazio, o una virgola. Magari un '\n' quando passi alla "riga" successiva della matrice.

P.S. Non dimenticare di terminare buffer_A quando hai finito di aggiungere cifre.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:05
Domenica, 17/01/2021
Testo quotato

Postato originariamente da AldoBaldo:
contenere 010203040511121314152122232425, cioè tutti i numeri "appiccicati" e praticamente illeggibili: è nelle tue intenzioni?


se sa che sono sempre coppie di due caratteri, la stringa è leggibile!

Ultima modifica effettuata da Carlo il 18/01/2021 alle 0:25


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 699
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:36
Domenica, 17/01/2021
Certo che sì, Carlo. Mi ponevo la questione della leggibilità immediata, a colpo d'occhio, ma in effetti non è detto che sia tra gli obiettivi che vuole/deve raggiungere mano17.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:46
Domenica, 17/01/2021
Testo quotato

Postato originariamente da AldoBaldo:

Certo che sì, Carlo. Mi ponevo la questione della leggibilità immediata, a colpo d'occhio, ma in effetti non è detto che sia tra gli obiettivi che vuole/deve raggiungere mano17.


Avevo capito il motivo della domanda, era per stimolare mano17 a darci altre info, visto che forse lavora con un microcontrollore.

comunque la void forma() non serve, /10 da le decine %10 da le unità, non so se gli può essere utile un codice scritto in C++, ma il suo compilatore C è simile basta sostiture BYTE con byte, il seguente codice preleva sequenzialmente le cifre numeriche in fomato byte dalle matrici bidimenzionali A1 e A2 e li scrive come coppie di caratteri ASCII nel vettore char buffer_A, gli indici del vettore in eccesso sono riempiti con il codice ASCII del carattere zero:
Codice sorgente - presumibilmente C#

  1. #include <iostream>
  2.  
  3. int main()
  4. {
  5.     BYTE A1[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
  6.     BYTE A2[2][7]={{21,22,23,24,25,26,27},{28,29,30,31,32,33,34}};
  7.     BYTE indice=0;
  8.     char buffer_A[90]; // numeri come coppie di caratteri con zero iniziale se serve
  9.  
  10.     for (BYTE i=0; i<3; i++){
  11.             for(BYTE c=0; c<5; c++){
  12.                 buffer_A[indice]=A1[i][c]/10+'0'; // converte le decine in carattere
  13.                 buffer_A[indice+1]=A1[i][c]%10+'0'; // converte le unità in carattere
  14.                 indice+=2;
  15.             }
  16.     }
  17.  
  18.     for (BYTE i=0; i<2; i++){
  19.             for(BYTE c=0; c<7; c++){
  20.                 buffer_A[indice]=A2[i][c]/10+'0'; // converte le decine in carattere
  21.                 buffer_A[indice+1]=A2[i][c]%10+'0'; // converte le unità in carattere
  22.                 indice+=2;
  23.             }
  24.     }
  25.  
  26.     for (BYTE i=indice; i<90; i++)
  27.         buffer_A[i]='0'; // riempie le posizioni restanti con il carattere zero
  28.  
  29.     // verifica finale su console
  30.     for (int i=0; i<89; i+=2)
  31.         printf("%c%c ", buffer_A[i], buffer_A[i+1]);
  32.  
  33.     return 0;
  34. }


Ultima modifica effettuata da Carlo il 18/01/2021 alle 16:09


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 699
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 17:50
Lunedì, 18/01/2021
Visto che intanto chi ha chiesto è già sparito (secondo tradizione) e che mi provochi :heehee:, Carlo, mi permetto di interloquire con te proponendo un'alternativa ancor più sintetica...

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <string.h>
  4.  
  5. #define DIM_BUFF    90
  6. #define Q_CIFRE      2    /* Q_CIFRE: quantita' delle cifre */
  7. #define QR_A1        3    /* QR: quantita' delle righe */
  8. #define QC_A1        5    /* QC: quantita' delle colonne */
  9. #define QR_A2        2
  10. #define QC_A2        7
  11.  
  12. typedef int8_t  BYTE;
  13. typedef int16_t WORD; /* due bytes */
  14.  
  15. int main() {
  16.     BYTE A1[QR_A1][QC_A1]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
  17.     BYTE A2[QR_A2][QC_A2]={{21,22,23,24,25,26,27},{28,29,30,31,32,33,34}};
  18.     BYTE i, c;
  19.     char buff[DIM_BUFF]; /* numeri come coppie di caratteri **
  20.                          ** con zero iniziale se serve      */
  21.  
  22.     WORD *p = (WORD*)buff; /* un puntatore ausiliario */
  23.  
  24.     for (i=0; i<QR_A1; i++)
  25.         for (c=0; c<QC_A1; c++)
  26.             *p++ = (WORD)(A1[i][c]/10+'0') | (((WORD)(A1[i][c]%10+'0'))<<8);
  27.  
  28.     for (i=0; i<QR_A2; i++)
  29.         for (c=0; c<QC_A2; c++)
  30.             *p++ = (WORD)(A2[i][c]/10+'0') | (((WORD)(A2[i][c]%10+'0'))<<8);
  31.  
  32.     memset( p, '0', DIM_BUFF-(((char*)p)-buff) ); /* completa con tutti '0' */
  33.  
  34.     /* verifica finale su console */
  35.     for (i=0; i<DIM_BUFF-1; i+=Q_CIFRE)
  36.         printf("%c%c ", buff[i], buff[i+1]);
  37.  
  38.     return 0;
  39. }



Poi magari il compilatore lo sviluppa in qualcosa di più "ponderoso" di quel che appare, e quasi sicuramente facendo così si va a intaccare l'affidabilità (ad esempio... che succede se cambia la cosiddetta endianness?), però lo trovo un trucchetto simpatico.

Ultima modifica effettuata da AldoBaldo il 19/01/2021 alle 1:17


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 0:30
Martedì, 19/01/2021
Ma allora vuoi che ti copro di domande... :yup::rotfl:
una cosa per volta:
Codice sorgente - presumibilmente Plain Text

  1. WORD *p = (WORD*)buff; /* un puntatore ausiliario */


Non voglio sapere perché hai dichiarato un puntatore ausiliario, non ho analizzato il resto del codice.
*p è un puntatore che punta un dato di due bytes (se si ok, se no spiega)
(WORD*)buff (non ho idea di cosa faccia e cosa verrà scritto su p)....:heehee:

Ultima modifica effettuata da Carlo il 19/01/2021 alle 0:32


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 699
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 1:16
Martedì, 19/01/2021
Sono giochetti coi puntatori. In sostanza, come sai, un puntatore non è altro che un numero che rappresenta un indirizzo in memoria nel quale è collocata una variabile di un certo tipo. A seconda del tipo, lo spazio occupato dalla variabile può essere diverso. In C, incrementare un puntatore significa passare all'indirizzo dell'elemento successivo, ovvero aggiungere al puntatore iniziale la quantità di byte che corrisponde alle dimensioni dell'elemento puntato (che dipendono dal tipo).

Ecco quindi che dovendo agire su coppie di char ho pensato di definire un tipo WORD, che non è altro che l'equivalente di una coppia di char (16 bit) e di creare un puntatore ausiliario di quel tipo nel quale collocare l'indirizzo del punto iniziale della memoria occupata dal buffer (un array di char).

A questo punto, se immetto un valore numerico a 16 bit in *p, finisco per impostare contemporaneamente entrambi i char anziché uno solo. Inoltre, quando incremento p con p++ avanzo non di uno, ma di due byte in un colpo solo.

Ovviamente, prima dell'assegnamento devo "assemblare" il valore numerico a 16 bit accorpando due char in un solo WORD, e lo faccio con...

Codice sorgente - presumibilmente Plain Text

  1. *p++ = (WORD)(A1[i][c]/10+'0') | (((WORD)(A1[i][c]%10+'0'))<<8);



Questa riga fa un sacco di cose.

Codice sorgente - presumibilmente Python

  1. (WORD)(A1[i][c]/10+'0'), per il compilatore, è una versione a 16 bit della cifra
  2. delle decine; solo i primi 8 bit risultano utilizzati
  3.  
  4. ((WORD)(A1[i][c]%10+'0')), per il compilatore, è una versione a 16 bit della
  5. cifra delle unità; anche questo valore usa solo i primi 8 bit, ma...
  6.  
  7. <<8 con uno shift sposto quei bit per far spazio agli 8 del primo valore
  8.  
  9. | I due valori vengono "assemblati" con un or
  10.  
  11. Il valore a 16 bit (che equivale alle due cifre del numero convertito)
  12. risultante viene collocato in *p
  13.  
  14. Incrementando p, l'indirizzo avanza di due byte in un colpo solo, preparando il
  15. puntatore alla prossima impostazione



(WORD*)buff è semplicemente un cast per "convincere" il compilatore a usare senza lamentarsi l'indirizzo del buffer di char a 8 bit come se fosse l'indirizzo di un buffer di WORD a 16 bit.

P.S. Se vuoi intervenire sul codice ho provato a farne copia direttamente modificabile qui: https://codeshare.io/5ObL8g
Non ho mai usato quel servizio, quindi non so se e come funzioni. Se sei curioso, dacci un'occhiata.

Ultima modifica effettuata da AldoBaldo il 19/01/2021 alle 8:21


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo