PDA

View Full Version : [C++]:Devo scrivere su un file esterno


Bandit
27-07-2012, 12:24
Ciao a tutti ragazzi
ho queste due classi Veicolo e Automobile che eredita in maniera pubblica da Veicolo le funzioni che vengono ridefinite in questa classe automobile.
E la funzione write_data deve scrivere le info su un file esterno.
Le classi hanno stringhe dinamiche.
Vi posto ciò che ho scritto per inquadrare il problema ma il vero mio dubbio è l'ultima finestra di codice.



#ifdedine veicoli_h_
#define veicoli_h_

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

class Veicolo
{
private:

string *Marca;
string *Proprietario;

public:
Veicolo( string & mar, string &prop);
~Veicolo() {delete []Modello; delete []Proprietario};
virtual void print_data();
virtual void write_data();
};


class Automobile: public Veicolo
{
private:
string *Modello;
string *Targa;
int Cilindrata;

public:

Automobile(string & mar, string &prop , string &mod, string&tar, int cil = 0);
~Automobile() {delete []Modello; delete []Targa;};
virtual void print_data();
virtual void write_data()

}

#endif


vado ad implementare




include "veicoli.h"
Veicolo::Veicolo ( string & mar, string &prop)
{Marca = new string(mar);
Proprietario = new string (prop);}



Automobile::Automobile (string & mar, string &prop , string &mod, string&tar, int cil = 0)
{
Modello = new string(mod);
Targa = new string (tar);
Cilindrata=cil;
}


void Veicolo::print_data(){
cout<<"marca è =" <<Marca;
cout<<"proprietario è="<<Proprietario;}

void Automobile::printa_data(){
Veicolo::print_data();
cout<<"modello" <<Modello;
cout<<"targa"<<Targa;
cout<<"cilindrata"<<Cilindrata;
}







fin qui mi trovo alla perfezione l'ho postato solo per far inquadrare il problema.
Dovrei ora stampare su un file esterno le info, per esempio su testo.txt, tramite le funzioni write_data(). questo file di testo l'ho salvato dove, ho salvato questo codice.
Da quello che ho capito per stampare una cosa devo innanzitutto considerare una libreria di uscita tipo ostream o ofstream, andando ad includere nel codice come ho fatto all'inizio.
Poi devo assegnare uno stream al file che voglio usare (testo.txt)
quindi devo fare


void Veicolo::write_data(){

ostream fd; //fd è lo stream del file
fd.open ("testo.txt",ios::out|ios::app)

//in modo da poter scrivre sul file senza andar a cancellare le cose che scrivo

fd<<"Marca"<<Marca;
fd<<"Proprietario"<< Proprietario;
}

void Automobile::write_data()
{ Veicolo::write_data();
fd<<"Modello"<<Modello;

fd<<"targa"<<Targa;
fd<<"cilindrata"<<Cilindrata;

}



ho fatto bene?
che devo fare più per far scriveere le info su questo file esterno?

LarsSalazar
27-07-2012, 12:54
non vedo nel codice la chiusura del file.

I comandi per la scrittura sono quelli da te descritti qui un breve esempio:

// basic file operations
#include <iostream>
#include <fstream>
using namespace std;

int main () {
ofstream afile;
afile.open ("esempio.txt");
afile << "Scrivo qualcosa sul file!\n";
afile.close();
return 0;
}


L'outuput è questo:
[file esempio.txt]
Scrivo qualcosa sul file!

Bandit
27-07-2012, 15:27
c'è differenza tra ostream e ofstream a livello di programma?

non vedo nel codice la chiusura del file.

I comandi per la scrittura sono quelli da te descritti qui un breve esempio:

// basic file operations
#include <iostream>
#include <fstream>
using namespace std;

int main () {
ofstream afile;
afile.open ("esempio.txt");
afile << "Scrivo qualcosa sul file!\n";
afile.close();
return 0;
}


L'outuput è questo:
[file esempio.txt]
Scrivo qualcosa sul file!

Ciao Lars

e la chiusura che tu dici la devo porre, al termine delle due funzione write_data?


per fare una cosa del genere devo porre qualcosa nel costruttore?

bender86
27-07-2012, 17:31
Le classi hanno stringhe dinamiche.

Perché?
Modello, marca, targa e proprietario sono semanticamente stringhe. Perché tu le rappresenti come puntatori a stringa? Hai un buon motivo? Usare dei puntatori introduce la possibilità di fare errori nella loro gestione*, proprio per questo in C++ si usano il meno possibile.

* Errori che hai fatto tra l'altro. L'istruzione 'delete [] variabile;' ha senso solo se 'variabile' è un array, cioè se è stato allocato con 'new Tipo[dimensione];'. Ma non lo è, dato che lo hai allocato con 'new Tipo;'. Devi usare 'delete variabile;'. Anzi, devi evitare i puntatori.

Un altro errore sono gli argomenti dei costruttori: devi passare riferimenti a stringhe costanti:
Veicolo(const string & mar, const string & prop);

Per la tua domanda, il modo più semplice è di passare un argomento di tipo 'std::ostream &' alle tue funzioni 'write_data()'. In questo modo possono scrivere su qualsiasi stream, compreso 'cout', quindi puoi implementare 'print_data()' usando 'write_data()'.

...
virtual void print_data();
virtual void write_data(std::ostream & stream);
...


void Veicolo::print_data() {
// Chiama 'write_data()', che scrive su uno stream qualsiasi,
// e fagli scrivere su 'cout' (la console).
write_data(std::cout);
}

void Veicolo::write_data(std::ostream & stream) {
stream << "Marca: " << Marca << '\n';
stream << "Proprietario: " << Proprietario << '\n';
}

void Automobile::print_data() {
// Chiama 'write_data()', che scrive su uno stream qualsiasi,
// e fagli scrivere su 'cout' (la console).
write_data(std::cout);
}

void Automobile::write_data(std::ostream & stream) {
Veicolo::print_data(stream);

stream << "Modello: " << Modello << '\n';
stream << "Targa: " << Targa << '\n';
stream << "Cilindrata: " << Cilindrata << '\n';
}


A quel punto chiami quelle funzioni passando uno stream come parametro:


int main()
{
std::ofstream file;
file.open("esempio.txt");

Automobile auto("Ford", "Mr. Ford", "T", "TTT000");

// Stampa sulla console, usando 'cout'.
auto.print_data();

// Stampa sulla console, usando 'cout' (uguale a prima).
auto.write_data(std::cout);

// Stampa nel file 'esempio.txt'.
auto.write_data(file);

file.close();
}

Bandit
27-07-2012, 18:00
Ciao Bender

perchè il testo mi diceva che erano delle stringhe dinamiche, e poichè non le avevo mai incontrate ho aperto una discussione

http://www.hwupgrade.it/forum/showthread.php?t=2490286

ed infatti l'implementazione ricorda la soluzione che mi ha mostrato Kendal
quindi a questo punto non so come creare classi con stringhe dinamiche



ma questo std:: lo posso evitare di scrivere se metto sopra a tutto
using namespace std?
non l'ho mai visto nemmeno sul libro quel comando e seppure mi rende le cose facili non lo riesco a capire