Newsgroup: it.comp.lang.c++
Titolo: I File

Problema
Memorizzare una matrice su un file e' una cosa banale il problema e' poi
andarla a leggere, perché  io scrivo su file dei numeri interi ( int ),
quando invece li devo andare a leggere per memorizzarli in una matrice, li
devo leggere come caratteri ( char ). Il problema non esisterebbe sei i
numeri della matrice fossero da 0 a 9 perché con una stupida conversione di
tipo
ES.
matrice[j][i]=(int)matrice[j][i]-48;
(48 e' il valore in codice ASCII di zero)
otterrei dei numeri che vanno da 0 a 9, formati da un solo carattere.
La mia matrice invece contiene numeri che aumentando possono arrivare a
valori dell'ordine di 10000 ovvero di 5 cifre, per cui non e' piů cosě
semplice andarli a leggere e non so poi come fare a codificarli.
Ringrazio anticipatamente tutti quelli che avranno la voglia di aiutarmi a
risolvere questo problema
Grazie a Tutti in anticipo


wrote:


 andarla a leggere,
Scrivere i numeri sul file uno alla volta con qualcosa di semplice tipo
ofstream ofs( "tuofile" );
for ( int riga = 0; riga < NUMRIGHE; ++riga )
    for ( int colonna = 0; colonna < NUMCOLONNE; ++colonna )
        ofs << matrice[ riga ][ colonna ] << " ";
o qualcosa di simile, dovrebbe (dico "dovrebbe") essere il sistema più
portabile.
EMG

 all'indirizzo di un altro int che usi per la lettura...
Non molto portabile, temo, dato che il suo funzionamento dipende
strettamente dalla dimensione del tipo int assunta.
EMG

sizeof int... ma rimane sempre l'eventuale problema della sequenza
intel o motorola...
Luc.


 wrote :
| Luc wrote:
| >
| > Puoi memorizzarli in 'binario' scrivendo sul file ad esempio i 4 byte
| > che compongono l'int e poi rileggendoli inserendo questi 4 byte
| > all'indirizzo di un altro int che usi per la lettura...
|
| Non molto portabile, temo, dato che il suo funzionamento dipende
| strettamente dalla dimensione del tipo int assunta.
Usando il sizeof(int) almeno non saranno portabili solo i files, mentre il
programma si.
oppure si possono usare dei tipi di dato a grandezza predefinita,
cercandone con il sizeof uno che abbia lunghezza 4 byte (oltre agli int, di
solito, i puntatori a void e gli enum, oppure vedere se e' definito
__int32).
il tutto a livello di preprocessore
#ifndef A_4_BYTES_TYPE
if(sizeof (int) == 4){
    #define A_4_BYTES_TYPE
    typedef int datum;
} else
if (sizeof (void *) == 4) {
    #define A_4_BYTES_TYPE
    typedef void* datum;
}
else
...
#endif
#ifndef A_4_BYTES_TYPE
#error no 4 bytes type found!
#endif

portabile.
Solo se i numeri vengono scritti esplicitamente su righe di testo.
Il sistema e' portabile solo in questo modo o altrimenti adottando un
proprio formato binario, ma resta sempre il problema della
riconversione e del corretto "endianess" da adottare.

 wrote :

il gcc ha delle funzioni apposite, che agiscono solo se necessaria la
conversione: sono fondamentalmente degli #ifdef valutati a compile time, e
non fanno nulla in caso di inutilita' della funzione. possono essere usati
meccanismi simili per rendere endianess-free la propria classe.

 >
Per risolvere questo problema basta fare (credo):
#include <fstream>
void write(std::ostream& os, const int& i)
{
   const void* base = &i;      // locazione in memoria
   const char* buf = static_cast<const char*>(base);
   os.write(buf, sizeof(i));
}
void read(std::istream& is, int& i)
{
  char buf[sizeof(int)];
  is.read(buf, sizeof(int));
  if(is)
  {
    void* base = buf;     // locazione in memoria
    i = *static_cast<int*>(base);
  }
}
Ovviamente in questo modo possiamo leggere e scrivere solo con un programma compilato
con lo stesso compilatore.
Ma il codice in se dovrebbe essere portabile.
Inoltre il file deve essere aperto in modalità binaria.
Manlio Perillo

 riconversione e del corretto "endianess" da adottare.
Infatti pensavo proprio al formato testo.
EMG