Oppure

Loading
17/01/21 10:53
mano17
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:

byte A1[3][5];
byte A2[2][7];
byte indice=0;
char buffer_A[90];
for (byte i=0;i<3;i++){for(byte c=0;c<5;c++){forma(A1[i][c]);indice=indice+2;}
                       }
for (byte a=0;a<2;a++){for(byte b=0;b<7;b++){forma(A2[a][b]);indice=indice+2;}
                       }
void forma(byte X){        //per convertire byte in char

       #define N 2
     char a[N];
          itoa(X,a,10);  //converto il numero byte X in char
     byte l1 = strlen (a);
          memmove (a + (N - l1), a, l1);
          memset (a, '0', N - l1);    //riempio di 0 i vuoti
          for (byte i=0;i<N;i++){buffer_A[indice+i+1]=a[i];
}
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 17/01/21 10:54
17/01/21 14:08
Carlo
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 17/01/21 14:22
in programmazione tutto è permesso
17/01/21 17:11
AldoBaldo
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...

// gli spazi li ho inseriti solo
// per incolonnare le celle
[ 1][ 2][ 3][ 4][ 5]
[11][12][13][14][15]
[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.
17/01/21 21:05
Carlo
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 17/01/21 23:25
in programmazione tutto è permesso
17/01/21 21:36
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.
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.
17/01/21 21:46
Carlo
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:
#include <iostream>

int main()
{
    BYTE A1[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
    BYTE A2[2][7]={{21,22,23,24,25,26,27},{28,29,30,31,32,33,34}};
    BYTE indice=0;
    char buffer_A[90]; // numeri come coppie di caratteri con zero iniziale se serve

    for (BYTE i=0; i<3; i++){
            for(BYTE c=0; c<5; c++){
                buffer_A[indice]=A1[i][c]/10+'0'; // converte le decine in carattere
                buffer_A[indice+1]=A1[i][c]%10+'0'; // converte le unità in carattere
                indice+=2;
            }
    }

    for (BYTE i=0; i<2; i++){
            for(BYTE c=0; c<7; c++){
                buffer_A[indice]=A2[i][c]/10+'0'; // converte le decine in carattere
                buffer_A[indice+1]=A2[i][c]%10+'0'; // converte le unità in carattere
                indice+=2;
            }
    }

    for (BYTE i=indice; i<90; i++)
        buffer_A[i]='0'; // riempie le posizioni restanti con il carattere zero

    // verifica finale su console
    for (int i=0; i<89; i+=2)
        printf("%c%c ", buffer_A[i], buffer_A[i+1]);

    return 0;
}
Ultima modifica effettuata da Carlo 18/01/21 15:09
in programmazione tutto è permesso
18/01/21 16:50
AldoBaldo
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...

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define DIM_BUFF    90
#define Q_CIFRE      2    /* Q_CIFRE: quantita' delle cifre */
#define QR_A1        3    /* QR: quantita' delle righe */
#define QC_A1        5    /* QC: quantita' delle colonne */
#define QR_A2        2
#define QC_A2        7

typedef int8_t  BYTE;
typedef int16_t WORD; /* due bytes */

int main() {
    BYTE A1[QR_A1][QC_A1]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};
    BYTE A2[QR_A2][QC_A2]={{21,22,23,24,25,26,27},{28,29,30,31,32,33,34}};
    BYTE i, c;
    char buff[DIM_BUFF]; /* numeri come coppie di caratteri **
                         ** con zero iniziale se serve      */

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

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

    for (i=0; i<QR_A2; i++)
        for (c=0; c<QC_A2; c++)
            *p++ = (WORD)(A2[i][c]/10+'0') | (((WORD)(A2[i][c]%10+'0'))<<8);

    memset( p, '0', DIM_BUFF-(((char*)p)-buff) ); /* completa con tutti '0' */

    /* verifica finale su console */
    for (i=0; i<DIM_BUFF-1; i+=Q_CIFRE)
        printf("%c%c ", buff[i], buff[i+1]);

    return 0;
}


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 19/01/21 0: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.
18/01/21 23:30
Carlo
Ma allora vuoi che ti copro di domande... :yup::rotfl:
una cosa per volta:
 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 18/01/21 23:32
in programmazione tutto è permesso