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
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. ^^;
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
Atttz! E' stato veramente bravo come dice di essere!
Sono impressionato.
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
ti aiuta spiros che è un informatico
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 *_*
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:
Un LOOP con un NOT EOF ... no?
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.
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
Citazioneti aiuta spiros che è un informatico
prendi per le mele mi sono connesso ora
e cmq il c++ non è il mio forte
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)
ma un .txt?^..
Yes un semplicissimo txt
archivio danneggiato 0_0
Mmmm strano cmq l'ho riuppato e per sicurezza rifatto...
zero sono col pc di un amico
e mi dice: cartella compressa non valida o danneggiata -.-''
copia icolla qui sul topic no eh?^
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;
}
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.
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...
Non mi sono dimenticato di te ... sono ancora in tempo?
Certo certo.... ho tempo fino agli inizi di febbraio per finirlo...
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! -.-'
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)