PDA

Visualizza la versione completa : [C++] Aprire un file in modalità "append"


mutuuu
08-01-2010, 16:20
Salve. Intanto mi presento.. sono nuovo di questo forum :)

Stavo provando a scrivere un po' di codice per approfondire gli stream da/sui file del c++. Questo è il codice "padre".


#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>
using namespace std;

void find_file(fstream & file, int choice);
void text_insert(fstream & file);
void error(int a);
void read(fstream & file);
void close(fstream & file);


main(){
fstream file;
int control; // variabile di controllo della selezione
cout << "Scrittura/lettura su File. Scegliere cosa fare:" << endl << endl;
cout << "[1] Scrivere su file" << endl;
cout << "[2] Leggere un file" << endl;
cout << "[3] Uscire dal programma" << endl << endl;
cout << "Numero selezione: ";
cin >> control;
switch(control){
case 1: break;
case 2: find_file(file, 1); /*chiamata alla
apertura del file in modalità lettura*/
read(file); // lettura
close(file); // chiusura del file
break;
case 3: exit(0); //chiusura del programma
default: error(1); /*sbaglio nel digitare
il numero. Chiamata alla funzione error */
}
cout << endl << "Scrittura su File. Scegliere cosa fare:" << endl << endl;
cout << "[1] Sovrascrivere il file" << endl;
cout << "[2] Aggiungere testo alla fine del file" << endl << endl;
cout << "Numero selezione: ";
cin >> control;
switch(control){
case 1: find_file(file, 2); /* chiamata
apertura file in modalità write*/
text_insert(file); //inserimento testo
close(file); //chiusura del file
break;
case 2: find_file(file, 3); /*chiamata apertura
file in modalità "append" */
text_insert(file); // inserimento testo
close(file); //chiusura del file
break;
default: error(1);}
}

void find_file(fstream & file, int choice){
char indirizzo[100];
cout << endl << "Inserire il percorso del file da leggere ";
cout << "o da scrivere, con l'estensione " << endl;
gets(indirizzo);
switch(choice){
case 1: file.open(indirizzo, ios::in);
//apertura in modalità read
break;
case 2: file.open(indirizzo, ios::out);
//apertura in modalità write
break;
case 3: file.open(indirizzo, ios::app);
//apertura in modalità append
break;
default: error(4);
}
if(!file){ //controllo sul caricamento del file
error(2); //se non è caricato, chiama la funzione error
}
cout << endl << "Caricamento del file eseguito correttamente" << endl << endl;
}

void text_insert(fstream & file){
cout << "Inserire il testo da copiare nel file destinazione, ";
cout << "quando vuoi terminare l'inserimento ";
cout << " scrivi / e premi invio." << endl << endl;
string a = "\0";
string b = "/";
while(cin.good()){ //finchè l'acquisizione è corretta
a = cin.get(); //acquisisci un carattere
if(a == b) /*controllo sull'inserimento
di "/" che fa terminare l'inserimento*/
break;
file << a; //stampa nel file il carattere acquisito
}
cout << endl << "Scrittura completata con successo" << endl;
}

void read(fstream & file){
char a;
cout << endl;
while(file.eof()!= true){ // finchè il file non è finito, leggilo :)
a = file.get(); //estrai un carattere dal file
cout << a; //stampa a video il carattere
}
cout << endl << endl << "Lettura completata con successo." << endl;
}

void close(fstream & file){
int choice;
file.close(); //chiusura del file
cout << "Programma terminato con successo! Vuoi riavviarlo?" << endl << endl;
cout << "[1] Yes" << endl;
cout << "[2] No" << endl << endl;
cout << "Numero selezione ";
cin >> choice;
switch(choice){
case 1: cout << endl << "Riavvio programma " << endl << endl;
main(); //chiamata al main, riavvio del programma
case 2: cout << "Programma terminato";
exit(0); //uscita dal programma
default: error(1);
}
}

void error(int a){
switch(a){
case 1: cout << endl << "E' stato inserito una lettera ";
cout << "o un numero non valido" << endl;
break;
case 2: cout << endl << "Errore nel caricamento del file, ";
cout << "o il file non esiste" << endl;
break;
default: cout << endl << "Errore imprevisto" << endl;
}
cout << "Programma riavviato" << endl << endl;
main();
}


Allora questo è il codice padre, diciamo.. L'errore non è nè in fase di compilazione, nè di linking. Ce ne sono un paio di errori:

il primo- ho analizzato il file in modalità debug e ho visto che la funzione "gets(indirizzo)" non viene chiamata-- cioè quello che accade è che dopo aver scritto: "Inserire il percorso del file da leggere o da scrivere, con l'estensione" non aspetta che io inserisca il percorso, ma il programma va avanti e chiaramente mi sputa fuori l'errore di non caricamento del file.

Volendo potrei usare un'alternativa a gets ma non capisco perchè non funzioni.. come funziona per esempio in questo pezzo di codice del tutto identico:


#include <iostream>
#include <fstream>
using namespace std;
main(){
fstream file;
char indirizzo[100];
cout << endl << "Inserire il percorso del file da leggere o da scrivere, ";
cout << "con l'estensione " << endl;
gets(indirizzo);
file.open(indirizzo, ios::out);
if(!file){
cout << "Errore caricamento file";
main();
}
cout << endl << "Caricamento del file eseguito correttamente" << endl << endl;
cout << "Inserire il testo da copiare nel file destinazione, quando ";
cout << "vuoi terminare l'inserimento scrivi / e premi invio." << endl << endl;
string a = "\0";
string b = "/";
while(cin.good()){
a = cin.get();
if(a == b)
break;
file << a;
}
cout << endl << "Scrittura completata con successo" << endl;
int choice;
file.close();
cout << "Programma terminato con successo! Vuoi riavviarlo?" << endl << endl;
cout << "[1] Yes" << endl;
cout << "[2] No" << endl << endl;
cout << "Numero selezione ";
cin >> choice;
switch(choice){
case 1: cout << endl << "Riavvio programma " << endl << endl;
main();
case 2: cout << "Programma terminato";
exit(0);
default: cout << "Errore";
main();
}
}

Questo codice funziona benissimo.. si ferma al gets e mi fa inserire l'indirizzo.. mah :dhò:


Il secondo errore, invece, è dovuto al fatto forse che non ho ben capito la modalità append.. Cioè prendendo lo stesso codice che ho postato qua sopra (il secondo dei due postati) e mettendo:

ios::app invece di ios::out

mi da sempre "Errore caricamento file".. cioè come se il file non fosse aperto-- :dhò:

Qualcuno che abbia l'enorme pazienza di leggersi questo papiro.. Ne sarei grato ^^


P.S. alcuni pezzi di codice che potevano benissimo stare in una sola riga, li ho spezzati in due adesso in modo che non facesse venire l'odiosa barra di scorrimento orizzontale..

oregon
08-01-2010, 16:41
Prima della gets pulisci il buffer di input della tastiera. Scrivi una

cin.ignore();

Per il file in append, sei sicuro che ci sia l'errore? Puo' essere che era il nome del file non corretto per il primo problema?

E poi, tutte quelle chiamate a main() alla fine, non hanno senso. Non si richiama la funzione main dal suo interno (in modo ricorsivo). Se scrivi in quel modo, non equivale a passare il controllo al main come se ci fosse un "goto" ma significa chiamare una funzione esattamente come per le altre.

mutuuu
08-01-2010, 16:47
Originariamente inviato da oregon
Prima della gets pulisci il buffer di input della tastiera. Scrivi una

cin.ignore();

wow.. funziona :)



Per il file in append, sei sicuro che ci sia l'errore? Puo' essere che era il nome del file non corretto per il primo problema?

No, il nome del file è giusto-- :(


E poi, tutte quelle chiamate a main() alla fine, non hanno senso. Non si richiama la funzione main dal suo interno (in modo ricorsivo). Se scrivi in quel modo, non equivale a passare il controllo al main come se ci fosse un "goto" ma significa chiamare una funzione esattamente come per le altre.

hai ragione.. non ha senso ^^ ma è solo un esempio e la chiamata al main in modo ricorsivo permette solo di riavviare il programma.. Cmq ti do ragione :)

oregon
08-01-2010, 16:49
Originariamente inviato da mutuuu
No, il nome del file è giusto-- :(


Fino a prima di inserire la cin.ignore() non hai potuto inserire il nome del file ... come sapevi che ne veniva passato uno corretto?

Prova nuovamente adesso.

mutuuu
08-01-2010, 16:54
Originariamente inviato da oregon
Fino a prima di inserire la cin.ignore() non hai potuto inserire il nome del file ... come sapevi che ne veniva passato uno corretto?

Prova nuovamente adesso.

bè ho provato..

Cmq adesso ho anche osservato la variabile indirizzo a scanso di equivoci.. ed effettivamente l'indirizzo è giusto-- solo non mi si apre..

non passa mai questo controllo "if(!file)" e chiama sempre l' "error(2);".

oregon
08-01-2010, 16:54
Inserisci un nome di file/percorso particolare? E' un file che gia' esiste?

mutuuu
08-01-2010, 17:02
è un file che già esiste: è un punto txt.. quindi nulla di particolare

Ho provato con il percorso completo e con il percorso "relativo" (cioè quello che ti inserisce o cerca il file nella cartella dove si trova l'exe)

Per scrupolo ho provato pure a mettere l'indirizzo di un file che non esiste.. chiaramente stesso risultato.

La cosa curiosa è che usando ios::out funziona (e quindi mi sovrascrive il file esistente)-- ma l'append no..

oregon
08-01-2010, 17:05
Guarda ... ho provato scrivendo

prova.txt

in append e non ho avuto errori ...

mutuuu
08-01-2010, 17:13
sta cosa è stranissima..

Ci sto perdendo la testa..

creo il file prova.txt e lo metto nella cartella dove c'è l'eseguibile (desktop).

Lancio il programma -> premo 1 -> 2 -> inserisco "prova.txt" invio (ovviamente senza le virgolette)

Risultato: Errore nel caricamento del file, o il file non esiste.

Faccio la stessa cosa, ma con l'indirizzo assoluto " c:\documents and settings\mattia\desktop\prova.txt "

Stesso risultato.

Faccio sempre la solita cosa però con un file che non esiste "prova2.txt". Solito risultato. Idem con l'indirizzo assoluto. :madai!?:

oregon
08-01-2010, 17:28
Esegui il .exe oppure lo fai dall'IDE (quale IDE?).

Loading