PDA

View Full Version : [c++] problema stringhe in programma classi


uaoke_88
29-04-2009, 15:24
salve a tutti mi sono appena registrato al forum e voglio subito sottoporvi il problema che mi ha fatto perdere mezza mattinata...
O creato questo semplice programma che implementa la classe libro, ma durante l'esecuzione dopo aver acquisito i primi due campi stringa si interrompe.
penso sia un problema relativo alle stringhe stesse anche perchč hop provato a farlo partire inserendo solo le variabili int e float e non dava alcun problema...vi posto di seguito i tre file su cui si sviluppa...

//libro.h
#ifndef _Libro_
#define _Libro_
#include <cstdlib>
#include <iostream>
#include <string>

class libro
{
private:
char * titolo;
int numpagine;
float prezzo;
char * genere;
char * autori;

public:
libro();
int get_numpagine() {return numpagine;}
float get_prezzo() {return prezzo;}
char* get_titolo(){return titolo;}
char* get_genere() {return genere;}
char* get_autori() {return autori;}
void set_titolo(char* nome) {titolo=new char[strlen(nome)+1];
strcpy(titolo,nome);}
void set_autori(char* nome) {genere=new char[strlen(nome)+1];
strcpy(autori,nome);}
void set_genere(char* nome) {autori=new char[strlen(nome)+1];
strcpy(genere,nome);}
void set_numpagine(int num) {numpagine=num;}
void set_prezzo(float valore) {prezzo=valore;}
void stampa_scheda(libro l);
libro scrivi_scheda();
~libro() {delete[] titolo;delete[] genere;delete[] autori;}
};
#endif
----------------------------------------------------------------------------------------------------------------------------
//libro.cpp
#include "libro.h"
using namespace std;

libro::libro()
{
numpagine=0;
prezzo=0;
}

libro libro:: scrivi_scheda()
{
libro l;
float valore;
int num;
char* nome=new char[50];
cout<<"Inserimento dati libro \n";
cout<<"Inserisci titolo: ";

cin.getline(nome,50);

l.set_titolo(nome);
cout<<"\nInserisci autore: ";

cin.getline(nome,50);

l.set_autori(nome);
cout<<"\nInserisci il genere: ";

cin.getline(nome,50);

l.set_genere(nome);
cout<<"\nInserisci il numero di pagine: ";
cin>>num;
l.set_numpagine(num);
cout<<"\nInserisci il prezzo: ";
cin>>valore;
l.set_prezzo(valore);
delete [] nome;
return l;

}

void libro:: stampa_scheda(libro l)
{
cout<<"\n Titolo: "<<l.get_titolo();
cout<<"\n Autore: "<<l.get_autori();
cout<<"\n Genere: "<<l.get_genere();
cout<<"\n Numero pagine: "<<l.get_numpagine();
cout<<"\n Prezzo: "<<l.get_prezzo()<<"\n ";
}
----------------------------------------------------------------------------------------------------------------------------
//main.cpp
#include "libro.h"
using namespace std;

int main(int argc, char *argv[])
{
libro opera;
float np; //nuovo prezzo

opera=opera.scrivi_scheda();

system("PAUSE");

opera.stampa_scheda(opera);

cout<<"Modifica prezzo \n";
cout<<"Vecchio prezzo: "<<opera.get_prezzo()<<" \n";
cout<<"Nuovo prezzo: ";
cin>>np;
opera.set_prezzo(np);

system("PAUSE");
return EXIT_SUCCESS;
}

ringrazio anticipatamente tutti coloro che si prodigheranno nel darmi una mano...

BrutPitt
29-04-2009, 15:43
Ho dato solo una rapida occhiata.... ma qui:

char* nome;
cout<<"Inserimento dati libro \n";
cout<<"Inserisci titolo: ";

cin.getline(nome,50);


manca l'allocazione di *nome... prima di acquisire la stringa.

P.S.
Ma perche' non usi la classe "string" ... visto che hai anche inserito l'include?

:)

uaoke_88
29-04-2009, 16:10
ho messo anche l'allocazione dinamica di nome, ma continua a fare lo stesso problema.
mi dici quali funzioni usare con la classe string per acquisire la stringa,purtroppo sulle slide del professore ho trovato solo quest'alternativa...
inoltre avevo anche un'altro dubbio...dovendo usare sempre lo stesso puntatore(nome) per copiare titolo,autore e genere non dovrei anche pulire il buffer dopo ogni inserimento?? grazie...

wizard1993
29-04-2009, 16:18
string str;
cin>>str;
cout<<str;

string ha inoltre l'overload per molti operatori e tante funzioni interessanti
http://www.cplusplus.com/reference/string/string/

uaoke_88
29-04-2009, 16:25
purtroppo il testo dell'esercizio diceva esplicitamente di usare dei puntatori a char...comunque,non vorrei farti perdere tempo...perņ perchč non copi i tre file nel dev??? tanto il programma compila...si blocca dopo l'acquisizione della seconda stringa...infatti ho provato ad acquisire solo le variabili int e float...e una sola stringa con le altre due variabili, e funziona perfettamente fino alla fine...appena provo a inserire '2' stringhe si blocca...cosa puņ essere??

BrutPitt
29-04-2009, 16:44
Nessun problema a usare i char*, soprattutto se hai dei vincoli dettati da un esercizio.

Lo dicevo solo perche' notavo una serie di allocazioni, ma nessuna deallocazione... :)

Con l'allocazione dinamica, cio' che allochi devi preoccuparti anche a deallocarla...

Cosi' nel'esempio in questione... immagino avrai fatto:

char* nome = new char[50+1];
cout<<"Inserimento dati libro \n";
cout<<"Inserisci titolo: ";

cin.getline(nome,50);


dovrai necessariamente, prima del return scrivere:

delete nome;
return l;


Ma anche le allocazioni fatte con le funzioni:
void set_titolo(char* nome) {titolo=new char[strlen(nome)+1];
strcpy(titolo,nome);}
void set_autori(char* nome) {genere=new char[strlen(nome)+1];
strcpy(autori,nome);}
void set_genere(char* nome) {autori=new char[strlen(nome)+1];
strcpy(genere,nome);}

dovrebbero essere gestite da un distruttore di opera.

ancora...

nome puo' essere riutilizzato con piu' di una "getline"... visto che fai la copia del contenuto... e alla successiva getline il contenuto viene sovrascritto.

BrutPitt
29-04-2009, 16:57
Edit

uaoke_88
30-04-2009, 16:15
corretto il problema dell'allocazione...ora perņ dopo aver inserito le stringhe visualizza dei caratteri strani al posto di titolo,autori e genere...non riesco proprio a capire...

ps: inserisco nel mio post le correzioni fatte al programma...

tomminno
30-04-2009, 16:29
corretto il problema dell'allocazione...ora perņ dopo aver inserito le stringhe visualizza dei caratteri strani al posto di titolo,autori e genere...non riesco proprio a capire...

ps: inserisco nel mio post le correzioni fatte al programma...

Provare il debugger?

BrutPitt
30-04-2009, 18:08
Se allochi correttamente la memoria in:

void set_autori(char* nome) {genere=new char[strlen(nome)+1];
strcpy(autori,nome);}
void set_genere(char* nome) {autori=new char[strlen(nome)+1];
strcpy(genere,nome);}


In autori allochi genere... e in genere allochi autori.
Ma se avessi usato il debugger, come ha scritto tommino te ne saresti accorto, da solo, tre giorni fa.



Non usare una dichiarazione del genere...

libro libro::scrivi_scheda()
{
libro l;
...
...
return l; //viene chiamato il distruttore di l
}

Su return viene chiamato il distruttore di l... e deallocata la memoria.

scrivi_scheda() e' gia' membro di libro... per cui puoi accedere direttamente ai membri per mofdificarli... per cui, in questo contetso, puo' andar bene un:

void libro::scrivi_scheda()

In alternativa, se ti serve avere una "copia" di libro... la puoi passare via referenza dichiarando la funzione:

void libro::scrivi_scheda(libro &l)

oppure operi un'allocazione dinamica, tipo:

libro* libro::scrivi_scheda()
{
libro *l = new libro;
...
...
return l; //qui il distruttore non viene chiamato, visto che e' allocato dinamicamente... verra' chiamato sul "delete"
}

ma ti devi preoccupare di chiamare delete sull'oggetto restituito da scrivi_scheda().