Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2011
    Messaggi
    144

    [C] problema con stampa_matrice allocata dinamicamente

    Ciao a tutti,

    sto cercando di scrivere un programma in C che riesca a caricare una matrice da file e stamparla a video.

    Il codice finora scritto è il seguente:

    codice:
    #include <stdio.h>#include <stdlib.h>
    #define MAX_C 50
    #define MAX_R 50
    
    
    typedef char** matrix;
    int R, C;
    matrix matricevip;
    void leggi_matrice(const char* nomefile, matrix m, int *r, int *c);
    void stampa_matrice(matrix m, int r, int c);
    
    
    int main(int argc, char *argv[])
    {
    
    
        char* nomefile = argv[1];
    
    
        if(argc!=2)
        {
            printf("Numero di argomenti inseriti errato!\n");
            exit(EXIT_FAILURE);
        }
        else
        {
            //metto la & prima delle variabili per indicare che sto effetuando un passaggio di parametri per riferimento (ovvero per indirizzo)
            //e non per valore
    
    
            leggi_matrice(nomefile, matricevip, &R, &C);
    
    
                stampa_matrice(matricevip, R, C);
    
    
        }
    
    
        return 0;
    }
    
    
    
    
    void leggi_matrice(const char* nomefile, matrix m, int *r, int *c)
    {
        //**matricevip è un doppio puntatore(un puntatore per le righe e uno per le colonne)
       char buffer[MAX_C], *res, temp;
       int i = 0, j = 0;
       FILE *ptrvip = fopen(nomefile, "r");
       if(nomefile == NULL)
          printf("Impossibile aprire il file %s\n", nomefile);
       else
       {
          printf("File %s letto correttamente!\n\n", nomefile);
          //Acquisizione numero di colonne
          res = fgets(buffer, MAX_C, ptrvip);
    
    
          while(res[i] != '\0')
          {
                *c = *c +1;
             i++;
          }
          C = *c;
    
    
          //Riposiziono il cursore all'inizio del file
          fseek(ptrvip, 0, 0);
    
    
    
    
          //Conto il numero della righe
          while(1)
          {
             res = fgets(buffer, MAX_R, ptrvip);
             if(res == NULL)
                break;
             *r = *r + 1;
          }
    
    
          R = *r;
    
    
          //Allocazione dinamica della memoria
          m = (char**) malloc (*c * sizeof(char*));//alloco lo spazio per le colonne
          for(i = 0; i < *c; i++)
             m[i] = (char*) malloc (*r * sizeof(char));//alloco lo spazio per le righe
    
    
          //Riposiziono il cursore all'inizio del file
          fseek(ptrvip, 0, 0);
    
    
          //Caricamento della matrice da file
    
    
          while(!feof(ptrvip))
          {
             for(i = 0; i < *r; i++)
                for(j = 0; j < *c; j++)
                {
                   fscanf(ptrvip, "%c", &temp);
                   if(temp != '\0')
                      m[i][j] = temp;
    
    
                }
    
    
          }
    
    
          fclose(ptrvip);
       }
    }
    
    
    void stampa_matrice(matrix m, int r, int c)
    {
        printf("\n");
        int i,j;
        for (i=0;i<r;++i)
            {
            for (j=0;j<c-1;++j)
                printf("%c",m[i][j]);
            printf("\n");
            }
        printf("\n");
    }
    La lettura del file e il caricamento della matrice va a buon fine, ma il programma smette di funzionare non appena richiamo la funzione "stampa_matrice".
    Qualcuno è in grado di capire il perchè?

    Grazie
    Ultima modifica di mbistato; 18-08-2014 a 12:59

  2. #2
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    Ciao

    codice:
    int R, C;
    Dichiari le variabili, ma non le inizializzi a 0, quindi le incrementi e poi utilizzi, sicuramente il loro valore non è quello che ti aspetti, probabile che nella funzione stampa superi le dimensioni della matrice.
    fammi sapere se l'errore era questo.
    Tecnologia

  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2011
    Messaggi
    144
    Ho inizializzato le variabili ma il problema persiste.

    Il contenuto del mio file è il seguente:

    JohnLennonXXXXX
    PaulMcCartneyXX
    GeorgeHarrisonX
    RingoStarrXXXXX
    StuartSutcliffe
    Ho fatto una verifica facendomi stampare la matrice man mano che viene caricata modificando il seguente pezzo di codice:

    codice:
    while(!feof(ptrvip))
          {
             for(i = 0; i < R; i++)
                for(j = 0; j < C; j++)
                {
                   fscanf(ptrvip, "%c", &temp);
                   if(temp != '\0'){
                      m[i][j] = temp;
                      printf("%c", m[i][j]);
                    }
                }
                printf("\n");
    
    
          }
    Il risultato della stampa è:

    JohnLennonXXXXX
    PaulMcCartneyXX
    GeorgeHarrisonX
    RingoStarrXXXXX
    StuartSutcliffee
    In pratica mi stampa una "e" in più al fondo.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Nel codice esistono tanti problemi "minori" (ad esempio, che senso ha controllare con feof la fine del file se sai esattamente quanti caratteri leggere? Oppure controllare if(nomefile == NULL) invece di controllare l'handle restituito dalla fopen).

    Ma la questione che genera l'errore è un'altra. Alla funzione leggi_matrice devi passare un puntatore a matrix (ovvero un puntatore triplo)

    matrix *m

    altrimenti non potrai mai modificarlo all'interno della funzione.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Aug 2011
    Messaggi
    144
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Nel codice esistono tanti problemi "minori" (ad esempio, che senso ha controllare con feof la fine del file se sai esattamente quanti caratteri leggere? Oppure controllare if(nomefile == NULL) invece di controllare l'handle restituito dalla fopen).
    Il testo del problema dice che non si conosce a priori la dimensione del file, ecco il motivo per cui uso feof.
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Ma la questione che genera l'errore è un'altra. Alla funzione leggi_matrice devi passare un puntatore a matrix (ovvero un puntatore triplo)

    matrix *m

    altrimenti non potrai mai modificarlo all'interno della funzione.
    Ho provato ma ottengo errori quando alloco lo spazio in memoria.

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX_C 50
    #define MAX_R 50
    
    
    
    
    typedef char** matrix;
    int R, C;
    matrix *matricevip;
    void leggi_matrice(const char* nomefile, matrix *m, int *r, int *c);
    void stampa_matrice(matrix *m, int r, int c);
    
    
    
    
    int main(int argc, char *argv[])
    {
    
    
    
    
        char* nomefile = argv[1];
    
    
    
    
        if(argc!=2)
        {
            printf("Numero di argomenti inseriti errato!\n");
            exit(EXIT_FAILURE);
        }
        else
        {
            //metto la & prima delle variabili per indicare che sto effetuando un passaggio di parametri per riferimento (ovvero per indirizzo)
            //e non per valore
    
    
    
    
            leggi_matrice(nomefile, matricevip, &R, &C);
    
    
    
    
                stampa_matrice(matricevip, R, C);
    
    
    
    
        }
    
    
    
    
        return 0;
    }
    
    
    
    
    
    
    
    
    void leggi_matrice(const char* nomefile, matrix *m, int *r, int *c)
    {
        //**matricevip è un doppio puntatore(un puntatore per le righe e uno per le colonne)
       char buffer[MAX_C], *res, temp;
       int i = 0, j = 0;
       FILE *ptrvip;
       if((ptrvip=fopen(nomefile, "r"))== NULL)
          printf("Impossibile aprire il file %s\n", nomefile);
       else
       {
          printf("File %s letto correttamente!\n\n", nomefile);
          //Acquisizione numero di colonne
          res = fgets(buffer, MAX_C, ptrvip);
    
    
    
    
          while(res[i] != '\0')
          {
                *c = *c +1;
             i++;
          }
          C = *c;
    
    
    
    
          //Riposiziono il cursore all'inizio del file
          fseek(ptrvip, 0, 0);
    
    
    
    
    
    
    
    
          //Conto il numero della righe
          while(1)
          {
             res = fgets(buffer, MAX_R, ptrvip);
             if(res == NULL)
                break;
             *r = *r + 1;
          }
    
    
    
    
          R = *r;
    
    
    
    
          //Allocazione dinamica della memoria
          m = (char**) malloc (*c * sizeof(char*));//alloco lo spazio per le colonne
          for(i = 0; i < *c; i++)
             m[i] = (char*) malloc (*r * sizeof(char));//alloco lo spazio per le righe
    
    
    
    
          //Riposiziono il cursore all'inizio del file
          fseek(ptrvip, 0, 0);
    
    
    
    
          //Caricamento della matrice da file
    
    
    
    
          while(!feof(ptrvip))
          {
             for(i = 0; i < *r; i++)
                for(j = 0; j < *c; j++)
                {
                   fscanf(ptrvip, "%c", &temp);
                   if(temp != '\0')
                      m[i][j] = temp;
    
    
    
    
                }
    
    
    
    
          }
    
    
    
    
          fclose(ptrvip);
       }
    }
    
    
    
    
    void stampa_matrice(matrix *m, int r, int c)
    {
        printf("\n");
        int i,j;
        for (i=0;i<r;++i)
            {
            for (j=0;j<c-1;++j)
                printf("%c",m[i][j]);
            printf("\n");
            }
        printf("\n");
    }

    Domanda: come posso fare senza allocare dinamicamente la matrice in memoria?

    Sto cercando la strada più semplice per farlo ma questi puntatori mi mettono il bastone tra le ruote

    Ho provato a fare quest'altra prova ma mi da errore quando richiamo le funzioni nel main in cui gli passo la matrice:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX_C 50
    #define MAX_R 50
    
    
    int R, C;
    void leggi_matrice(const char* nomefile, char mat[][MAX_C]);
    void stampa_matrice(char mat [][MAX_C]);
    void salva_file(const char* nomefile, char mat [][MAX_C]);
    void delete_c(char mat [][MAX_C], int colonna);
    void delete_r(char mat [][MAX_C], int riga);
    
    
    
    
    int main(int argc, char *argv[])
    {
        char tipo;
        char matricevip[MAX_R][MAX_C];
        int numero;
        char* nomefile = argv[1];
    
    
        if(argc!=2)
        {
            printf("Numero di argomenti inseriti errato!\n");
            exit(EXIT_FAILURE);
        }
        else
        {
            leggi_matrice(matricevip, nomefile);
            stampa_matrice(matricevip);
        }
    
    
        printf("\n");
        printf("Comando: ");
        scanf("%c %d", &tipo, &numero);
        //La riga che segue serve per togliere l'invio dal buffer
    
    
        while(tipo != 'x'){
        switch(tipo)
            {
            case 'c':
    
    
                if(!numero){
                    printf("Errore: colonna non specificata!\n");
                }
                else if(numero < 0 || numero > C){
                    printf("Errore: il numero della colonna specificata eccede la dimenzione max del file!\n");
                }
                else
                {
                    printf("test_1");
                    delete_c(matricevip, numero);
                    printf("Rimossa colonna %d", numero);
                    stampa_matrice(matricevip);
    
    
                }
    
    
                printf("Comando: ");
                scanf("%c %d", tipo, &numero);
                continue;
    
    
            case 'r':
                if(!numero){
                    printf("Errore: riga non specificata!\n");
                }
                else if(numero < 0 ||numero > R){
                    printf("Errore: il numero della riga specificata eccede la dimenzione max del file!\n");
                }
                else
                {
                    delete_r(matricevip, numero);
                    printf("Rimossa riga %d", numero);
                    stampa_matrice(matricevip);
    
    
                }
    
    
                printf("Comando: ");
                scanf("%c %d", tipo, &numero);
                continue;
    
    
            case 'q':
                salva_file(nomefile, matricevip);
                break;
    
    
            default:
                printf("Comando non valido");
                exit(EXIT_FAILURE);
                break;
    
    
    
    
            }
        }
    
    
        return 0;
    }
    
    
    
    
    void leggi_matrice(const char* nomefile, char mat[MAX_R][MAX_C])
    {
        //**matricevip è un doppio puntatore(un puntatore per le righe e uno per le colonne)
       char buffer[MAX_C], *res, temp;
       int i = 0, j = 0, R = 0, C = 0;
       FILE *ptrvip = fopen(nomefile, "r");
       if(nomefile == NULL)
          printf("Impossibile aprire il file %s\n", nomefile);
       else
       {
          printf("File %s letto correttamente!\n\n", nomefile);
          //Acquisizione numero di colonne
          res = fgets(buffer, MAX_C, ptrvip);
    
    
          while(res[i] != '\0')
          {
                C = C +1;
             i++;
          }
    
    
          //Riposiziono il cursore all'inizio del file
          fseek(ptrvip, 0, 0);
    
    
    
    
          //Conto il numero della righe
          while(1)
          {
             res = fgets(buffer, MAX_R, ptrvip);
             if(res == NULL)
                break;
             R = R + 1;
          }
    
    
          //Riposiziono il cursore all'inizio del file
          fseek(ptrvip, 0, 0);
    
    
          //Caricamento della matrice da file
    
    
          while(!feof(ptrvip))
          {
             for(i = 0; i < R; i++)
                for(j = 0; j < C; j++)
                {
                   fscanf(ptrvip, "%c", &temp);
                   if(temp != '\0')
                      mat[i][j] = temp;
                }
                printf("\n");
    
    
          }
    
    
          fclose(ptrvip);
       }
    }
    
    
    
    
    
    
    void stampa_matrice(char mat[MAX_R][MAX_C])
    {
        printf("\n");
        int i,j;
        for (i=0;i<R;++i)
            {
            for (j=0;j<C;++j)
                printf("%c", mat[i][j]);
            }
        printf("\n");
    }
    
    
    
    
    void salva_file(const char* nomefile, char mat[MAX_R][MAX_C]){
        int i = 0, j = 0;
        FILE *ptrvip = fopen(nomefile, "w");
        if(nomefile == NULL)
            printf("Impossibile aprire il file %s\n", nomefile);
        else{
            for(i=0; i<R; i++){
                for(j=0; j<C; j++)
                {
                fprintf(ptrvip, "%c\n", mat[i][j]);
                }
                fprintf(ptrvip, "%c\n", '\n');
            }
       }
    
    
    }
    
    
    void delete_c(char mat[MAX_R][MAX_C], int colonna){
    
    
        int i,j;
        if(colonna == C-1)
            C = C - 1;
        else{
            for(i=0; i<R; i++){
                for(j=colonna; j<C; j++)
                {
                mat[i][j] = mat[i][j+1];
                }
            }
                C = C - 1;
        }
            printf("La matrice è: \n");
    
    
            stampa_matrice(mat);
    
    
    }
    
    
    
    
    void delete_r(char mat[MAX_R][MAX_C], int riga){
    
    
        int i,j;
        if(riga == R-1)
            R = R - 1;
        else{
            for(i=riga; i<R-1; i++){
                for(j=0; j<C; j++)
                {
                mat[i][j] = mat[i+1][j];
                }
            }
                R = R - 1;
        }
            printf("La matrice è: \n");
    
    
            stampa_matrice(mat);
    
    
    }
    Ultima modifica di mbistato; 19-08-2014 a 08:37

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Quote Originariamente inviata da mbistato Visualizza il messaggio
    Il testo del problema dice che non si conosce a priori la dimensione del file, ecco il motivo per cui uso feof.
    Ma questo vale fino a quando non hai trovato R e C
    Una volta trovate il numero di colonne e righe la feof non ti serve più

    Domanda: come posso fare senza allocare dinamicamente la matrice in memoria?
    Risposta: non puoi

    Sto cercando la strada più semplice per farlo ma questi puntatori mi mettono il bastone tra le ruote
    I puntatori sono il cuore di C. Se non li comprendi e non sai utilizzarli, praticamente non potrai utilizzare il C.

    Ti ho detto di utilizzare un puntatore triplo ma non mi pare tu l'abbia fatto. Devi passare il puntatore a matricevip

    leggi_matrice(&matricevip, nomefile);

    modificando opportunamente la funzione leggi_matrice
    Ultima modifica di oregon; 19-08-2014 a 14:45
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2011
    Messaggi
    144
    Si ok cmq ho risolto senza allocare la memoria dinamicamente :-D

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Non puoi risolvere senza allocare la memoria se non sai quanto è grande il file ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #9
    Utente di HTML.it
    Registrato dal
    Aug 2011
    Messaggi
    144
    Quote Originariamente inviata da oregon Visualizza il messaggio
    Non puoi risolvere senza allocare la memoria se non sai quanto è grande il file ...
    Dal testo del problema, so che il file non supera le dimensioni MAX_R x MAX_C

    Ecco il codice funzionante:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #define MAX_R 50
    #define MAX_C 50
    
    
    int main(int narg, char *argv[])
    {
        char mat[MAX_R][MAX_C];
        /*il vettore riga mi serve per andare a*/
        char riga[MAX_R];
        /*op sta per operazione e sarebbe quello che tu hai chiamato "tipo" nel tuo programma*/
        char op;
        /*posizione invece sarebbe il numero della riga o della colonna che hai scelto di cancellare*/
        int pos;
        /*eff_r ed eff_c sono rispettivamente il numero di righe e colonne della matrice di caratteri letta dal file*/
        int eff_r, eff_c;
    
    
        int i,j;
        FILE *fp;
        /*flag_ciclo è una variabile che useremo per ciclare l'esecuzione del programma finche non si verificano errori o finchè l'utente non esca
        dal programma*/
        int flag_ciclo;
    
    
        if (narg!=2)
        {
            printf("Numero di parametri errato. \n");
            exit (1);
        }
    
    
        fp = fopen(argv[1], "r");
        if (fp == NULL)
        {
            printf("Errore nell'apertura del file %s \n", argv[1]);
            exit (1);
        }
    
    
        i = 0;
        /*leggo il file puntato da fp carattere per carattere e lo immagazzino in mat[i] (questo è quello che fa la funzione fgets).
        Il while si conclude quando si arriva alla fine del file*/
        while (fgets(mat[i],MAX_C,fp)!=NULL)
        {
            i++;
        }
        fclose(fp);
    
    
        printf("File %s letto correttamente. \n", argv[1]);
    
    
        /*memorizzo nella variabile effc la lunghezza di ogni riga (nota che sottraggo 1 perchè l'ultimo carattere presente nel vettore di stringhe
        mat è il terminatore di stringa '\0' che ovviamete non devo contare). Dunque effc rappresenta il numero di colonne della matrice*/
        eff_c = strlen(mat[0])-1;
    
    
        /*analogamente eff_r sarà il numero di righe della matrice che era memorizzato nella variabile i incrementata
        durante il while precedente*/
        eff_r = i;
    
    
        flag_ciclo = 0;
        /*tale ciclo mi serve perchè ogni volta che do il comando da tastiera, a fine esecuzione, il programma deve permettermi di digitare
        ulteriori comandi (in caso ti spiego meglio a voce)*/
        while(!flag_ciclo)
        {
            printf("Comando: ");
            /*La funzione gets brutalmente legge tutta la stringa corrispondente all’assegnazione e la funzione sscanf
            la scompone nei due elementi nome e valore del nome. La funzione sscanf restituisce il numero di campi che sono stati letti, in
            questo caso sarebbero 2: op e pos */
            gets(riga);
            j = sscanf(riga,"%c %d",&op,&pos);
    
    
            /*Qui ci sono due controlli per verificare che il numero di riga o di colonna sia stato immesso sulla linea di comando*/
            if ((op == 'r')&&(j == 1))
            {
                printf("Errore riga non specificata \n");
            }
            else if ((op == 'c')&&(j == 1))
            {
                printf("Errore colonna non specificata \n");
            }
            else
                /*Se l'utente ha inserito il comando completo verifico in quale caso mi trovo:*/
                switch(op)
                {
                  case 'x':
                      printf("Programma terminato senza salvataggio. \n");
                      return 1;
                      break;
                  case 'r':
                      /*se la posizione inserita supera il massimo numero di righe della matrice e/o la posizione < 1, visualizzo l'errore*/
                    if ((pos > eff_r)||(pos < 1))
                    {
                        printf("Errore: riga non specificata correttamente \n");
                        break;
                    }
                    else
                    {
                        //Rimuovi riga: copio ciclicamente riga+1 in riga e tolgo una riga totale
                        printf("Rimossa riga %d. La matrice contiene:\n", pos);
                        for (pos = pos-1; pos < (eff_r-1); pos++)
                        {
                            /*la funzione strcpy copia il contenuto di mat[pos+1] in mat[pos]. In pratica per eliminare la riga, sovrascrivo
                            la riga+1 in riga */
                            strcpy(mat[pos],mat[pos+1]);
                        }
                        /*decremento, giustamente, il numero di righe della matrice*/
                        eff_r--;
    
    
    
    
                            //Stampo la matrice dopo l'operazione
                            for (i = 0; i<eff_r; i++)
                            {
                                for (j = 0; j< eff_c;j++)
                                {
                                    printf("%c", mat[i][j]);
                                 }
                            printf("\n");
                            }
    
    
                    }
                    break;
                  case 'c':
                      /*al solito controllo che la posizione della colonna scelta sia una posizione ammissibile, ovvero che non superi i
                      limiti inferiore e superiore*/
                    if ((pos > eff_c)||(pos < 1))
                    {
                        printf("Errore: colonna non specificata correttamente \n");
                        break;
                    }
                    else
                    {
                        //Rimuovi colonna: copio ciclicamente colonna+1 in colonna e tolgo una colonna totale
                        printf("Rimossa colonna %d. La matrice contiene:\n", pos);
                        for (i = 0; i < eff_r; i++)
                            for (j = pos - 1; j < (eff_c-1);j++)
                                {
                                    /*qui avrei potuto utilizzare anche la funzione strcpy come fatto per le righe*/
                                        mat[i][j] = mat[i][j+1];
                                }
                        eff_c--;
    
    
                            //Stampo la matrice dopo l'operazione
                            for (i = 0; i<eff_r; i++)
                            {
                                for (j = 0; j< eff_c;j++)
                                {
                                    printf("%c", mat[i][j]);
                                 }
                            printf("\n");
                            }
                    }
                    break;
                  case 'q':
                    //Salvo il file copiando il contenuto della matrice nel file.
                  fp = fopen (argv[1], "w");
                  if (fp == NULL)
                    {
                        printf("Errore nell'apertura del file %s in scrittura \n", argv[1]);
                        exit (1);
                    }
                   for (i = 0; i<eff_r; i++)
                      {
                        for (j = 0; j< eff_c;j++)
                           {
                                    fprintf(fp,"%c", mat[i][j]);
                            }
                            fprintf(fp,"\n");
                      }
                    fclose(fp);
                    printf("Il file %s e' stato salvato correttamente. \n", argv[1]);
                    return 1;
                    break;
                  default:
                    printf("Errore: comando sconosciuto \n");
                }
        }
    
    
    
    
    
    
    
    
        return 0;
    }

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Quote Originariamente inviata da mbistato Visualizza il messaggio
    Dal testo del problema, so che il file non supera le dimensioni MAX_R x MAX_C
    Questo cambia le cose, così il problema è diverso. Avresti dovuto precisarlo prima ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.