FFsaga.it Forum

Beyond Final Fantasy => Informatica & Tecnologia => Discussione aperta da: zerocool il 27 Dicembre 2004, 21:06:13

Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 27 Dicembre 2004, 21:06:13
Visato che al mio topicone sulla programmazione hanno risposto in parecchi che conoscono i c++ ora siete obbligati ad aiutarmi.... :bleh:

Vi espongo il problema... il 10 ho l'esame di fondamenti di prog 1 e devo consegnare il primo progetto... tale progetto comporta la gestione di un'ipotetica iscrizione a quello che preferite...
Il file legge i dati da un file chiamato persone.txt strutturato in questa maniera:

Nome1
Cognome1
Data_nascita1
Nome2
Cognome2
Data_nascita2
...
...
...

il sorgente è abbastanza lungo quindi ecco il LINK (http://conted.altervista.org/gestione.cpp).

il problema sorge quando cerco di leggere il file in quanto mi da un errore di Segmentation fault su linux, mentre su win si pianta tutto  
provabilmente l'errore è nella lettura del file perchè se leggo solamente la prima riga funziona tutto, mentre se tento di leggere il resto partono i problemi, quindi se qualcuno ha un'idea mi aiuti....
Grazie già da ora
Titolo: Problemone C++ Per Esamone
Inserito da: lukelf il 28 Dicembre 2004, 00:07:30
Il link non mi caga. Volevo vedere in che modalità avevi aperto il file.
Comunque appena sistemi il link do il tuo problema in pasto al massimo esperto mondiale di C++. Almeno così dice. ^^;
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 00:11:08
Strano a me il linkozzo funziona cmq ho risolto... so come ma nn ho capito il perchè...

è bastato sostituire le linee
in.get(nome, 50)
...
etc

con:

in>> database[k].nome
...
etc
Titolo: Problemone C++ Per Esamone
Inserito da: lukelf il 28 Dicembre 2004, 00:43:09
Atttz! E' stato veramente bravo come dice di essere!

Sono impressionato.  
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 00:46:29
  L'unico problema è che nn so perchè in un modo funziona e nell'altro no...
per il resto basta dare un occhio alla libreria fstream per vedere che l'operatore >> è in overloading per gli oggetti di tipo stream... il resto viene da solo
Titolo: Problemone C++ Per Esamone
Inserito da: Alternative-One il 28 Dicembre 2004, 00:58:25
ti aiuta spiros che è un informatico
Titolo: Problemone C++ Per Esamone
Inserito da: Tidus™ il 28 Dicembre 2004, 01:00:37
Citazionealla libreria fstream

per vedere che l'operatore >>


è in overloading




per gli oggetti di tipo stream...



















il resto viene da solo
ma il capolavoro è


"il resto viene da solo"


*____________________________________________________________*




 


*se ne va a braccietto cn la sua ignoranza*


ccietto?


...... ccetto...... boh........................


ignoranza *_*
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 18:49:24
Ok ho perfezionato il programma, e l'ho modificato in modo da usare oggetti invece di una struct... adesso mi rimane un solo problema da risolvere... riuscire a fare in modo che all'apertura del file persone.txt non venga letta l'ultima riga...

Spirossino mio dove sei....  :love:
Titolo: Problemone C++ Per Esamone
Inserito da: lukelf il 28 Dicembre 2004, 18:51:10
Un LOOP con un NOT EOF ... no?
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 18:59:30
Si ovio per leggero

while(!file.eof())
{
}

il problema che il mio file per necessità ha una linea vuota alla fine fatta solo dal carattere \0 e vorrei che la lettura ignorasse questa riga poichè leggenda mi inizializza un'oggetto della classe persona di troppo e per giunta vuoto.
Titolo: Problemone C++ Per Esamone
Inserito da: lukelf il 28 Dicembre 2004, 19:02:35
Okkey ... magari non è pulito ma metti un controllo nel LOOP e verificane il contenuto. Se è lungo 0 o 2 byte lo butti 'che sei arrivato alla fine.
I due caratteri è nel caso tu abbia nel file un CRLF o un LFCR (x unix).

Edit: metti un controllo sul contenuto della stringa che stai leggendo
Titolo: Problemone C++ Per Esamone
Inserito da: spiros il 28 Dicembre 2004, 19:10:20
Citazioneti aiuta spiros che è un informatico
prendi per le mele mi sono connesso ora  
e cmq il c++ non è il mio forte
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 19:10:20
Ho già provato... ma con scarsi risultati... nn so se per un mio problema nel riuscire nell'implementarlo nel codice o perchè nn mi riconosce il test sulla condizione di ugualglianza...

Intanto vi posto anche il nuovo codice con in più il file persone per farvi un idea del problema... così se qualcuno mi trova la soluzione mi fa passare l'esame con più di 18  :help:


Gestione (http://conted.altervista.org/gestione.zip)
Titolo: Problemone C++ Per Esamone
Inserito da: spiros il 28 Dicembre 2004, 19:10:49
ma un .txt?^..
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 19:12:30
Yes un semplicissimo txt
Titolo: Problemone C++ Per Esamone
Inserito da: spiros il 28 Dicembre 2004, 19:25:02
archivio danneggiato  0_0
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 19:34:37
Mmmm strano cmq l'ho riuppato e per sicurezza rifatto...
Titolo: Problemone C++ Per Esamone
Inserito da: spiros il 28 Dicembre 2004, 19:37:24
zero sono col pc di un amico
e mi dice: cartella compressa non valida o danneggiata  -.-''
copia icolla qui sul topic no eh?^
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 28 Dicembre 2004, 20:27:46
Ecco a voi signori e signore...  

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

class persona{
   private:
      string nome;
      string cognome;
      string data_nascita;
   public:
      persona()
      {
         //Costruttore di default
      }
      
      ~persona()
      {
         //distruttore di default
      }
      
      persona(string n, string c, string d)
      {
         nome = n;
         cognome = c;
         data_nascita = d;
      }
      
      bool operator== (persona x)
      {
         if(nome == x.nome && cognome == x.cognome && data_nascita == x.data_nascita) return true;
         else return false;
      }
      
      void stampa()
      {
         cout<<"Nome: "<<nome<<endl;
         cout<<"Cognome: "<<cognome<<endl;
         cout<<"Data di nascita: "<<data_nascita<<endl;
         return;
      }
      
      void carica_lista(istream& lista)
      {
            lista >> nome;
            lista >> cognome;
            lista >> data_nascita;
            return;
      }
      
      void salva_lista(ostream& lista)
      {
         lista << nome<<endl;
         lista << cognome<<endl;
         lista << data_nascita<<endl;
         return;
      }
      
      void aggiungi(string n, string c, string d)
      {
         nome = n;
         cognome = c;
         data_nascita = d;
         return;
      }
      
      bool ricerca(char tipo, string chiave)
      {
         switch(tipo)
         {
            case 'n':
               if(nome == chiave) return true;
               break;
            case 'c' :
               if(cognome == chiave) return true;
               break;
         }
         return false;         
      }
      
      void cancella(persona suc)
      {
         nome = suc.nome;
         cognome = suc.cognome;
         data_nascita = suc.data_nascita;
      }
};

persona database[50];
ifstream in;
ofstream out;

void visualizza(int k)
{
   for(int i = 0; i < k; i++)
   {
      cout<<"\t\t\tPersona "<<i+1<<endl;
      database.stampa();
   }
   cout<<endl;
}

int apri()
{
   in.open("persone.txt");
   int k = 0;
   if(in.fail())
   {
      cout<<"\t\t\tErrore nell'apertura del file"<<endl;
   }
   else
   {
      while(!in.eof())
      {
         database[k].carica_lista(in);   
         k++;
      }
      cout<<"\t\t\tArchivio aperto con successo"<<endl;
   }
   in.close();
   return k;
}
void salva(int k)
{
   out.open("persone.txt");
   for(int i = 0; i < k; i++)
   {
      database.salva_lista(out);
   }
   out.close();
}

void aggiungi(int k)
{
   string nome;
   string cognome;
   string data;
   
   cout<<"Nome: ";
   cin>>nome;
   cout<<"Cognome: ";
   cin>>cognome;
   cout<<"Data di nascita: ";
   cin>>data;
   database[k].aggiungi(nome, cognome, data);
}

void elimina(int k)
{
   int p;
   cout<<"Inserisci il numero della persona da eliminare"<<endl;
   cin>>p;
   for(int i = 0; i < k; i++)
   {
      if(database == database[p] )
      {
         for(int j = p - 1; j < k; j++)
         {
            database[j].cancella(database[j+1]);
         }
      }
   }
   return;
}

int ricerca(char t, int k)
{
   string cerca;
   bool trovato;
   switch(t)
   {
      case 'n':
         cout<<"\t\t\tRicerca per nome..."<<endl;
         cin>>cerca;
         for(int i = 0; i < k; i++)
         {
            trovato = database.ricerca(t, cerca);
            if(trovato == true) return i;
         }
         break;
      case 'c':
         cout<<"\t\t\tRicerca per cognome..."<<endl;
         cin>>cerca;
         for(int i = 0; i < k; i++)
         {
            trovato = database.ricerca(t, cerca);
            if(trovato == true) return i;
         }
         break;
   }
   return -1;
}

void menu()
{
   cout<<"1. Inserisci una nuova persona"<<endl;
   cout<<"2. Visualizza l'elenco delle persone"<<endl;
   cout<<"3. Ricerca una persona"<<endl;
   cout<<"4. Elimina una persona"<<endl;
   cout<<"5. Esci"<<endl;
   return;
}

void menu_ricerca()
{
   cout<<"1. Ricerca per nome"<<endl;
   cout<<"2. Ricerca per cognome"<<endl;
   return;
}

int main()
{
   int n_persone;
   n_persone = apri();
   while(true)
   {
      int scelta = 0;
      menu();
      while((scelta != 1) && (scelta != 2) && (scelta != 3) && (scelta != 4))
      {
         cin>>scelta;
         switch(scelta)
         {
            case 1:
               aggiungi(n_persone);
               n_persone++;
               break;
            case 2:
               visualizza(n_persone);
               break;
            case 3:
               int ric;
               int risultato;
               menu_ricerca();
               cin>>ric;
               switch(ric)
               {
                  case 1:
                     risultato = ricerca('n', n_persone);
                     if(risultato != -1)
                     {
                        cout<<"\t\t\tTrovata corrispondenza alla persona: "<<endl;
                        database[risultato].stampa();
                     }
                     else cout<<"\t\t\tNessuna corrispondenza"<<endl;
                     break;
                  case 2:
                     risultato = ricerca('c', n_persone);
                     if(risultato != -1)
                     {
                        cout<<"\t\t\tTrovata corrispondenza alla persona: "<<endl;
                        database[risultato].stampa();
                     }
                     else cout<<"\t\t\tNessuna corrispondenza"<<endl;
                  break;
                  default:
                  cout<<"Operazione non valida"<<endl;
                  return 0;
               }
               break;
            case 4:
               elimina(n_persone);
               n_persone--;
               break;
            case 5:
               salva(n_persone);
               return 0;
            default:
               cout<<"Scelta non valida"<<endl;
               cin>>scelta;
         }
      }
      }
   salva(n_persone);
   return 0;
}
Titolo: Problemone C++ Per Esamone
Inserito da: lukelf il 29 Dicembre 2004, 12:20:25
Oddio ... senza indentazione è terribile. Mi sono già "incartato" tre volte.
Fase 1: zero, mi mandi il txt via PM o Mail, pls?

Fase 2: possibile soluzione
io mi aspetto che da qualche parte, durante la lettura della stringa/riga del file TXT ci debba essere un controllo sul contenuto (che non ho trovato); questo controllo dovrebbe verificare alcune possibilità che vado a descrivere. Infatti secondo me il file potrebbe terminare in questi diversi modi:

contenutoriga[CR][LF] (dove ci sono un numero imprecisato di byte che leggi)
[CR][LF][EOF] (dove leggi 2 byte escluso il EOF)

oppure

contenutoriga[CR][LF] (dove ci sono un numero imprecisato di byte che leggi)
[EOF] (dove leggi 0 byte escluso il EOF)

Diciamo quindi pure che se tu verifichi la lunghezza del contenuto della stringa durante la fase di lettura (credo con una length) e ottieni un valore inferiore o uguale a 2 byte e poi subito dopo un EOF, l'ultima lettura la devi buttare. E' come se ... tutte le volte che verifichi la lunghezza della stringa letta ottieni <= a 2 allora devi fare una seconda lettura del file per verificare se subito dopo c'è l'EOF o qualcosa di analogo.

Mi rendo conto che è complicato spiegarlo a parole e non ho un compilatore sotto mano per provare.

Fammi sapere.
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 29 Dicembre 2004, 17:33:46
CitazioneOddio ... senza indentazione è terribile. Mi sono già "incartato" tre volte.
Fase 1: zero, mi mandi il txt via PM o Mail, pls?

Fase 2: possibile soluzione
io mi aspetto che da qualche parte, durante la lettura della stringa/riga del file TXT ci debba essere un controllo sul contenuto (che non ho trovato); questo controllo dovrebbe verificare alcune possibilità che vado a descrivere. Infatti secondo me il file potrebbe terminare in questi diversi modi:

contenutoriga[CR][LF] (dove ci sono un numero imprecisato di byte che leggi)
[CR][LF][EOF] (dove leggi 2 byte escluso il EOF)

oppure

contenutoriga[CR][LF] (dove ci sono un numero imprecisato di byte che leggi)
[EOF] (dove leggi 0 byte escluso il EOF)

Diciamo quindi pure che se tu verifichi la lunghezza del contenuto della stringa durante la fase di lettura (credo con una length) e ottieni un valore inferiore o uguale a 2 byte e poi subito dopo un EOF, l'ultima lettura la devi buttare. E' come se ... tutte le volte che verifichi la lunghezza della stringa letta ottieni <= a 2 allora devi fare una seconda lettura del file per verificare se subito dopo c'è l'EOF o qualcosa di analogo.

Mi rendo conto che è complicato spiegarlo a parole e non ho un compilatore sotto mano per provare.

Fammi sapere.
mmm il problema è che nn riesco a fare sti controlli... e il forum nn accetta l'indentazione... appena ti trovo su msn ti mando il sorgente...  
Titolo: Problemone C++ Per Esamone
Inserito da: lukelf il 3 Gennaio 2005, 15:50:01
Non mi sono dimenticato di te ... sono ancora in tempo?
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 3 Gennaio 2005, 20:32:42
Certo certo.... ho tempo fino agli inizi di febbraio per finirlo...
Titolo: Problemone C++ Per Esamone
Inserito da: lukelf il 6 Gennaio 2005, 11:37:33
Buongiorno zero, mi servirebbe il file che utilizzi per le prove. Quello che usi in lettura.
Postalo quì (che tanto non credo che i tab siano significativi) oppure mandalo via mail.

P.S.: Il compilatore mi ha dato degli errori e ho dovuto fare delle correzioni ma, nonostante il corretto risultato ottenuto, c'è qualcosa che non mi convince. Diciamo che mi si stanno accavallando le regole di Java e del C++ o che, più semplicemente, mi stò rincoglionendo. Comunque se mi mandi il file faccio le prove e ti rispedisco la parte di NON lettura del CRLF.

Per tutti gli altri che non fanno gli informatici: scegliete un altro lavoro! -.-'
Titolo: Problemone C++ Per Esamone
Inserito da: zerocool il 6 Gennaio 2005, 20:04:10
Per il file puoi crearlo anche tu è un semplice file txt chimato persone.txt strutturato in questo modo:

Mario
Rossi
23/05/1986
Carlo
Bianchi
12/06/1964
(riga vuota)