Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [ C++ ] Leggere e stampare una Matrice da filetext

    Ciao,da poco ho iniziato a studiare le operazioni sui file.
    Ora devo leggere una matrice di interi da un file di testo e stamparla a video, quindi devo sommare i suoi valori e stampare a video anche questo risultato.

    Con un array mi viene perfettamente.
    codice:
    #include "fileArray.h"
    
    void leggiArrayFile( vett v, int &r )
    {
         int register i;
         
         fstream file;
         file.open( SORGENTE, ios::in );
         
         if( !file )
         {
             cout<<"Il file non esiste!\n";
         }
         
         else{
                r = 0;
                while( !file.eof() )
                {
                       file>> v[ r ];
                       r++;
                }
         }
         
         for( i = 0; i < r; i++ )
         {
              cout<< v[ i ] << " ";
         }
         
         file.close();     
    }
    
    void sommaArrayFile( vett v, int &r )
    {
         int register i;
         int sArray = 0;
         
         for( i = 0; i < r; i++ )
         {
              sArray += v[ i ];
         }
         
         cout<<"\nLa somma degli interi contenuto nel file e' di: " << sArray;
    
    }
    Nel caso della matrice invece,per far stampare i numeri devo utilizzare un metodo diverso e in ogni caso non me li stampa seguendo lo schema della matrice( righe e colonne ) ma uno sotto l'altro.

    codice:
    #include "FileMatrici.h"
    
    void leggiMatriceFile( matrice m, int &r, int &c )
    {    
         int register i, j;
         
         fstream file;
         file.open( SORGENTE, ios::in );
         
         if( !file )
         {
             cout<<"Il file non esiste!\n";
         }
         else{
                file>> r;
                file>> c;
                for( i = 0; i < r; i++ )
                {
                     for( j = 0; j < c; j++ )
                     {
                          file>> m[ i ][ j ];
                     }
                     cout<< "\n";
                }
         }
                          
         for( i = 0; i < r; i++ )
         {
              for( j = 0; j < c; j++ )
              {
                   cout<< m[ i ][ j ];
              }
              cout<<"\n";
         }
         file.close();
    
    }
    
    void sommaMatriceFile( matrice m, int &r, int &c )
    {
         int register i, j;
         int sMatrice = 0;
         
         for( i = 0; i < r; i++ )
         {
              for( j = 0; j < c; j++ )
              {
                   sMatrice += m[ i ][ j ];
              }
         }
         
         cout<<"\nLa somma degli interi della matrice contenuti nel file e\' di: " << sMatrice << "\n";
         
    }
    In pratica in questo modo il primo numero scritto all'interno del file viene considerato riempimento.
    Il file in questo caso deve essere scritto così:
    codice:
    16
    1 1 1 1
    2 2 2 2
    3 3 3 3
    4 4 4 4
    Dove 16 serve per far capire al ciclco che deve leggere 16 valori in totale.

    Però io vorrei che il riempimento fosse calcolato,in base alla fine del file, così come viene fatto con l'array.
    Cioè in questo modo:

    codice:
              r = 0;
              c = 0;
              while( !file.eof() )
              {
                     file>> m[ r ][ c ];
                     r++;
                     c++;
              }
    In questo modo non bisogna aggiungere alcun numero alla matrice esistente nel file.
    Come posso fare per integrare questo metodo senza che mi spari una serie di numeri enormi che non riguardano la matrice scritta nel file?
    Grazie.
    Gli uomini imparano ad essere ben pensanti prima ancora di imparare a pensare (Albert Ellis)

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Qualcosa del genere?

    codice:
    #include <iostream>
    #include <fstream>
    
    #define r 3
    #define c 4
    
    using namespace std;
    
    int main()
    {
        int x[r][c];
        ifstream input_file;
    
        input_file.open("nome_del_file");
    
        for (unsigned int i = 0; i < r; i++) {
            for (unsigned int j = 0; j < c; j++) {
                if (! input_file.eof()) {
                    input_file >> x[i][j];
                    cout << x[i][j] << " ";
                }
            }
            cout << endl;
        }
    
        input_file.close();
    
        return 0;
    }
    In questo modo non c'è bisogno di indicare il numero degli elementi da leggere.
    every day above ground is a good one

  3. #3
    Ciao,grazie della risposta,ma così r e c rimangono statici perchè definiti,quindi per eventuali cambi all'interno del file,dovrei modificare sempre il sorgente,invece vorrei che sia il programma stesso a calcolare di volta in volta la grandezza della matrice contenuta nel file e ad adattare il calcolo.

    Ho provato a scrivere la stessa funzione che ho scritto per l'array,in "versione matrice"
    così:

    codice:
    void leggiMatriceFile( matrice m, int &r, int &c )
    {    
         int register i, j;
         
         fstream file;
         file.open( SORGENTE, ios::in );
         
         if( !file )
         {
             cout<<"Il file non esiste!\n";
         }
         else{
              r = 0;
              c = 0;
              while( file.eof() )
              {
                     file>> m[ r ][ c ];
                     r++;
                     c++;
              }
         }
                          
         for( i = 0; i < r; i++ )
         {
              for( j = 0; j < c; j++ )
              {
                   cout<< m[ i ][ j ] << " ";
              }
              cout<<"\n";
         }
         file.close();
    
    }
    Ma così facendo non mi stampa niente e il risultato delle funzione somma è sempre = 0.
    Potresti dirmi se si può adattare in qualche modo secondo quanto ho scritto qui,in modo che funzioni anche con la matrice oltre che con l'array?
    Gli uomini imparano ad essere ben pensanti prima ancora di imparare a pensare (Albert Ellis)

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Ma così facendo, cioè incrementando sia r che c ad ogni passo, ottieni l'effetto di leggere gli elementi solo nella diagonale principale (m[0][0], m[1][1], m[2][2] ecc...).

    Io pensavo che conoscessi a priori le dimensioni della matrice, o al massimo runtime così avresti potuto ricorrere all'allocazione dinamica. Comunque a questo punto puoi fare una così: leggi il file riga per riga con il metodo getline(), estrai dalla stringa ottenuta i numeri con la funzione strtok() e li converti in interi con atoi(), assegnandoli poi alla matrice. Chiaramente, a seconda di quanti numeri ci sono nella stringa saprai quanti elementi ha una riga.

    E' probabile che esista una soluzione più C++ like, ma al momento non mi viene in mente altro.
    every day above ground is a good one

  5. #5
    Oppure puoi considerare la matrice come un array normale con un solo indice disinteressandoti di r e c;
    Altrimenti ancora puoi controllare se hai letto un newline e incrementare r(perchè come ti ha detto YuYevon incrementando sempre sia r che c inserisci solo gli elementi della diagonale principale )..
    Forse è un pò troppo C like come soluzione

  6. #6
    Caspita è vero! Non ci avevo pensato eheheh,svista
    Comunque vorrei fare in modo che funzioni sempre,senza conoscere la dimensione della matrice contenuta nel file.
    La soluzione che proponi è alquanto laboriosa,fino ad ora ho visto solo strtok();
    Caspita pensavo fosse più semplice!
    Ora mi cimento un altro pò,grazie ad entrambi.
    Gli uomini imparano ad essere ben pensanti prima ancora di imparare a pensare (Albert Ellis)

  7. #7
    Mitico! Ho provato a scopiazzare quello che avevo scritto per l'array,e per non segnare solo la diagonale principale: ho integrato un for in un altro come solitamente si fa con le matrici,solo che gli ho dato come termine di ciclo !file.eof()
    A questo punto ho incrementato gli indici fino alla fine del file e mi stampa tutto!
    Senza dover mettere un valore iniziale per il riempimento che alterava la matrice nel file!

    codice:
    else{
           for( r = 0; !file.eof(); r++ )
           {
                for( c = 0; !file.eof(); c++ )
                {
                        file>> m[ r ][ c ];
                }
           }
    }
    Ora il problema è la stampa,in pratica non mi stampa la matrice per righe e colonne ma tutti i numeri in fila,come se non vedesse la struttura della matrice:

    codice:
    for( i = 0; i < r; i++ )
         {
              for( j = 0; j < c; j++ )
              {
                   cout<< m[ i ][ j ] << " ";
              }
              cout<<"\n";
         }
         file.close();
    
    }
    E' come se ignorasse il comando cout<<"\n";
    alla fine di ogni riga,non capisco perchè non lo veda.
    Gli uomini imparano ad essere ben pensanti prima ancora di imparare a pensare (Albert Ellis)

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da Riccardo88
    codice:
    else{
           for( r = 0; !file.eof(); r++ )
           {
                for( c = 0; !file.eof(); c++ )
                {
                        file>> m[ r ][ c ];
                }
           }
    }
    L'idea è giusta, ma l'implementazione sbagliata. Dal ciclo interno esci solo quando il file è finito, non quando hai raggiunto il fine riga. In pratica hai trasformato la matrice in un array, col rischio di sforare l'indice massimo per le colonne.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  9. #9
    Ah vero,in effetti è come se leggesse un'unica riga.
    Ma allora come scriveresti per fargli leggere le colonne correttamente?

    EDIT:
    Inserendo i riempimenti da main,e adattando il body.cpp così:
    codice:
    void leggiMatriceFile( matrice m, int &r, int &c )
    {    
         int register i, j;
         
         fstream file;
         file.open( SORGENTE, ios::in );
         
         if( !file )
         {
             cout<<"Il file non esiste!\n";
         }
         else{
              for( i = 0; i < r; i++ )
              {
                   for( j = 0; j < c; j++ )
                   {
                        file>> m[ i ][ j ];
                   }
              }
         }
                          
         for( i = 0; i < r; i++ )
         {
              for( j = 0; j < c; j++ )
              {
                   cout<< m[ i ][ j ] << " ";
              }
              cout<<"\n";
         }
         file.close();
    
    }
    Mi legge,stampa e calcola perfettamente la matrice,però bisogna appunto inserire i rimepimenti manualmente,però vorrei che il programma stesso da solo, capisse quanto è grande la matrice di volta in volta.
    Gli uomini imparano ad essere ben pensanti prima ancora di imparare a pensare (Albert Ellis)

  10. #10
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Premesso che non puoi scrivere oltre i limiti imposti alla matrice, devi adottare il metodo che ti ha indicato Yuvevon ( leggere con getline(), spezzare con strtok(), convertire con atoi() ).

    Un modo più " C++ " per fare quanto indicato ( che adotterei io, ma che richiede che tra numero e numero ci siano solo spazi) può essere questo (richiede <string> e <sstream>):

    codice:
         else{
             std::string line;
             while( getline(file,line) ) {
    	     c=0;
    	     std::istringstream iss(line);
    	     while ( iss >> m[r][c] ) c++;
    	     r++;
    	  }
         }
    Il procedimento di tokenizzazione e conversione è a carico dello istringstream.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.