#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define STRLEN 1024
#define MAX_ROWS 64 //numero massimo di righe (se è 10, 10 sarà accettato come input)
#define MAX_COLUMNS 64

void main(void)
  {
    char input[STRLEN];
    int **ppmatrice;
    int m,n,i_r,i_c,check,tot,a;
    /********** INPUT **********/
    printf("Ciao, dimmi il numero di righe m per creare una matrice m x n.");
    check=0;
    do
      {
        if(check<1)
          {
            printf("\nNumero di righe: m=");
            scanf("%s",input);
            m=atoi(input);
            if((m<=MAX_ROWS)&&(m>0))
              {
                printf("Ho ricevuto %d",m);
                check++;
              }
            else printf("Errore: inserisci un numero intero tra 1 e %d.",MAX_ROWS);
          }
        if(check>=1)
          {
            printf("\nNumero di colonne: n=");
            scanf("%s",input);
            n=atoi(input);
            if((n<=MAX_COLUMNS)&&(n>0))
              {
                printf("Ho ricevuto %d",n);
                check++;
              }
            else printf("Errore: inserisci un numero intero tra 1 e %d.",MAX_ROWS);
          }
      }
    while(check<2);
    tot=m*n;
    printf("\nCreero' una matrice %d x %d\n",m,n);
    /********** ALLOCAZIONE MEMORIA ***********/
    ppmatrice=(int**)malloc(sizeof(int*)*m);  //salva in ppmatrice l'indirizzo di un posto dove c'è abbastanza spazio per m puntatori a m righe
    //per creare le colonne, facciamo un for che divida ogni riga in n colonne.
    for(i_c=0;i_c<=n;i_c++)
      {
        *(ppmatrice+i_c)=(int*)malloc(sizeof(int)*n);
      }
    /********** RIEMPIMENTO MATRICE ***********/
    printf("Ora dammi i %d x %d = %d numeri per riempire la matrice\n",m,n,tot);
    
    for(i_r=0;i_r<m;i_r++)
      {
        for(i_c=0;i_c<n;i_c++)
          {
            printf("Elemento di posizione %d,%d: ",i_r+1,i_c+1);
            scanf("%s",input);
            *(*(ppmatrice+i_c)+i_r)=atoi(input);
          }
      }
    /********** STAMPARE MATRICE A SCHERMO **********/
    printf("Ecco la tua matrice:\n");
    for(i_r=0;i_r<m;i_r++)
      {
        for(i_c=0;i_c<n;i_c++)
          {
            a=*(*(ppmatrice+i_c)+i_r);
            if(a<0) printf("%d ",a); //questa distinzione con l'if è utile solo a livello grafico in modo che i numeri negativi siano allineati a quelli positivi
            else printf(" %d ",a); //eventualmenteè possibile cancellare <--- QUESTA <--- riga e rimuove l'if dalla precedente, lasciando solo printf("%d ",a); . Analogamente, la vriabile a non è necessaria in tal caso ed è possibile inserire *(*(ppmatrice+i_c)+i_r) all'interno del printf.
          }
        printf("\n");
      }
  }