View Full Version : [C++]Problema di I/0 su file
Kleidemos
24-04-2003, 17:29
Voglio leggere una determinata stringa che ho precedentemente salvato e leggerla fino ad un carattere stabilito( %end ).
Ho provato cosi:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
return 0;
}
void scrivi(string nome, string text)
{
string cosa;
stringstream temp_write;
ofstream out(nome.c_str());
temp_write << text;
text = temp_write.str();
out << text << "%end" << text;
out.close();
}
string leggi(string nome)
{
string cosa;
stringstream temp_read;
ifstream in(nome.c_str());
while(in.get() != "%end")
{
temp_read << in.put();
}
cosa = temp_read.str();
return cosa;
}
Ma mi da
C:/Documents and Settings/Admin/Desktop/Test.cpp:29: ISO C++ forbids comparison
between pointer and integer
C:/Documents and Settings/Admin/Desktop/Test.cpp:31: no matching function for
call to `std::basic_ifstream<char, std::char_traits<char> >::put()'
.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
Ciao da Kleidemos
C++ Programmer
.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
Kleidemos
24-04-2003, 19:49
Cosi nn compare nulla:(:(
#include <iostream>
#include <cstdio>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
void scrivi(string, string);
string leggi(string);
int main()
{
int sc;
string test = "this.txt", txt = "ioioio";
scrivi(test, txt);
cin >> sc;
if(sc == 1)
{
cout << leggi(test) << endl;
}
system("PAUSE");
return 0;
}
void scrivi(string nome, string text)
{
stringstream temp_write;
ofstream out(nome.c_str());
temp_write << text;
text = temp_write.str();
out << text << "%end%" << "ciao";
out.close();
}
string leggi(string nome)
{
string out, tmp, temp_read;
bool trovato = false;
ifstream in(nome.c_str());
while (in.good())
{
temp_read = in.get();
}
while(temp_read != "\0")
{
if(temp_read == "%end%")
{
out = temp_read;
trovato = true;
}
if(trovato)
continue;
}
in.close();
return out.c_str();
}
io per ricercare una stringa mi sono scritto questa banalità; se può esserti utile
#include "fstream.h"
#include "istream.h"
ifstream f( "filename.txt" );
string buf , findmystring = "cosa trovare";
while( f )
{
getline( f , buf );
for(int i=0;i < (int)buf.length();i++)
if(buf.substr(i,findmystring.length()) == findmystring)
printf(%s",buf.c_str());
}
Kleidemos
24-04-2003, 20:56
Ecco quel che il prog deve fare:
cerco di legere il files fino all simbolo, da me definito, %end%!
In pratica il files sara:
ioioio%end%ioioio
La var che stampero sara: ioioio !
La funz slava, va.
E che le funz leggi nn mi legge!
P.S: ho fatto male ad usare lo strinstream?
non puoi usare il terzo parametro di getline per dire dove smettere di leggere????
cmq io ho provato un ciclo di questo tipo while (!canale.eof()) e funziona
ciao
Kleidemos
25-04-2003, 09:30
tnk!
Ma cosi non va:
#include <iostream>
#include <cstdio>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
void scrivi(string, string);
string leggi(string);
int main()
{
int sc;
string test = "this.txt", txt = "ioioio";
scrivi(test, txt);
cin >> sc;
if(sc == 1)
{
cout << leggi(test) << endl;
}
system("PAUSE");
return 0;
}
void scrivi(string nome, string text)
{
stringstream temp_write;
ofstream out(nome.c_str());
temp_write << text;
text = temp_write.str();
out << text << "%end%" << "ciao";
out.close();
}
string leggi(string nome)
{
string out, temp_read;
bool trovato = false;
ifstream in(nome.c_str());
while (!in.eof())
{
temp_read = in.get();
}
out = temp_read.substr( 0, temp_read.find( "%end" ) );
in.close();
return out.c_str();
}
Scusate vado di fretta :ve lo spiego a voce :D
Vi complicate la vita inutilmente:
1-caricare tutto il file in una stl string
2-usare il metodo find della stringa che ritorna un iteratore diverso da end (oppure npos)se esiste la stringa da cercare.
3-leggi la stringa originale
da
tuastringa.begin() a iteratore_trovato_della_stringadacercare.
Sempre che io non abbia capito fischi per fiaschi della domanda :D
prova a usare getline(array_di_memorizzazione, grandezza_array,'%end%) senza alcun ciclo
Kleidemos
25-04-2003, 11:38
Originally posted by "ultio"
prova a usare getline(array_di_memorizzazione, grandezza_array,'%end%) senza alcun ciclo
cioe?
Skusate, ma sono molto niucco :cry:
getline regge tre parametri:
il primo è la variabile dove vuoi memorizzare quello che legge
il secondo è la dimensone massima da leggere
il terzo è il carattere che cerca prima di finire la lettura
se non inserisci il terzo parametro rimane di default '\n' (cioè a capo)
se tu ci metti '%end%' aspetta di trovare %end% prima di finire la lettura.
onde evitare errori è stata comunqeu data la precedenza al 2° parametro: se lo imposti a 40 e arriva a 40 caratteri senza trovare quello che cerca la lettura si interrompe comunque.
Kleidemos
25-04-2003, 11:55
string leggi(string nome)
{
string out, temp_read;
bool trovato = false;
ifstream in(nome.c_str());
while (in)
{
getline(out,/* che ci metto */ ,'%end%);
}
in.close();
return out.cstr();
}
su un array metti la sua dimensione, ma dato che usi una stringa metti un numero che sia abbastanza alto da far arrivare il programma all'%end&, e abbastanza basso da non tenere 20 gb di memoria :D
senza un array puoi scegliere tu...
volendo potresti leggere le dimensioni del file in byte e inserire il limite di conseguenza, ma non so se ne vale la pena, dipende dall'uso del programma... (se legge file dove al massimo vi sono 10000 caratteri puoi mettere il limite tranquillamente in base a questo)
ps: il ciclo non serve, a meno che tu non abbia più di un %end% nel file
Kleidemos
25-04-2003, 12:23
intendi cosi?
string leggi(string nome)
{
string out;
ifstream in( nome.c_str() );
in.getline(out, 500 ,'%end%');
in.close();
return out.c_str();
}
Il prog mi seriva per imparare come leggere/scrivere da/su file ;)
Sono scarso come idee, vero?
si, intendo così..
dovrebbe andare, sebbene non abbia mai usato c_str() :cry:
verloc...sinceramente il fatto di caricare l'intero file in una stringa non mi piace molto... Pensa se l'intero file fosse 2 Gb cosa succederebbe...
IMHO bisogna sempre mettersi nelle condizioni peggiori...
ultio: leggere con getline non si puà perchè il delimitatore deve essere un solo carattere...
Io lo farei così... L'ho un po' ampliato per utilizzare qualsiasi delimitatore...
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void scrivi(string nome, string text)
{
//L'avevi incasinato un po'...perchè hai usato stringstream ?
ofstream out(nome.c_str(), ios::app | ios::out);
out << text << "%end";
out.close();
}
//se apri e chiudi tutte le volte il file non ti avanzerà mai e leggerai
//sempre la prima stringa
#define BUFFER_LEN 1024
bool leggi(ifstream &in, string &text, const char *delim)
{
static string data;
char buff[BUFFER_LEN+1];
while(1)
{
if(data.size() > 0)
{
int pos = data.find(delim);
if(pos != string::npos)
{
text = data.substr(0, pos);
data = data.substr(pos+4);
return true;
}
}
if(in.eof())
{
text = data;
return false;
}
in.read(buff, BUFFER_LEN);
buff[in.gcount()] = '\0';
data += buff;
}
return false;
}
int main()
{
scrivi("pippo.txt", "ciao");
scrivi("pippo.txt", "ciao2");
ifstream in("pippo.txt");
string text;
while(leggi(in, text, "%end")) cout << text << endl;
in.close();
return 0;
}
Kleidemos
25-04-2003, 12:38
me lo spieghi meglio??
Cosi imparo e so risolverlo se mi capita ancora!
cmq........
tnk a tutti x la pazienza
ok, ne aprofitto...
se voglio gestire il file come binario? (ad esempio jpg e avi???)
parlo di un semplice copia-incolla, ma prima lo voglio memorizzare (come winmx o kazaa) durante il download
/\/\@®¢Ø
25-04-2003, 14:03
Originally posted by "Kleidemos"
Voglio leggere una determinata stringa che ho precedentemente salvato e leggerla fino ad un carattere stabilito( %end ).
La cosa piu' semplice secondo me e' questa:
#include <string>
#include <iostream>
using namespace std;
/* ... */
ifstream in(...); // il file da dove leggere
string s; // la "destinazione"
char c; // il "terminatore"
getline( in , s , c );
Kleidemos
25-04-2003, 14:12
Originally posted by "/\/\@®¢Ø"
La cosa piu' semplice secondo me e' questa:
Dici che mi complico troppo la vita?
P.S: ma perche nn posso utilizzare stringstream cionci?
Kleidemos
25-04-2003, 14:16
string leggi(string nome)
{
string termin = "%end";
string out;
ifstream in( nome.c_str() );
try
{
std::getline( in , out, termin );
}
catch(...)
{
cout << "Errore" <<endl;
}
in.close();
return out.c_str();
}
Cosi mi da errore dove è grassetto
/\/\@®¢Ø
25-04-2003, 14:19
Originally posted by "Kleidemos"
Dici che mi complico troppo la vita?
P.S: ma perche nn posso utilizzare stringstream cionci?
Azz.. no scusa forse ho sbagliato... a te interessa una stringa o un carattere !? ( "%end%" non e' un "carattere" effettivamente :D :p)
Kleidemos
25-04-2003, 14:20
Originally posted by "/\/\@®¢Ø"
Azz.. no scusa forse ho sbagliato... a te interessa una stringa o un carattere !? ( "%end%" non e' un "carattere" effettivamente :D :p)
Stringa!
"%end%"
queso legge sino a %end%
#include "fstream.h"
#include "istream.h"
ifstream f( "miofile.txt" );
string buf ;
while( f )
{
getline( f , buf );
if(!buf.find("%end%"))
printf("%s",buf.c_str());
}
/\/\@®¢Ø
25-04-2003, 15:06
Originally posted by "misterx"
queso legge sino a %end%
#include "fstream.h"
#include "istream.h"
ifstream f( "miofile.txt" );
string buf ;
while( f )
{
getline( f , buf );
if(!buf.find("%end%"))
printf("%s",buf.c_str());
}
Si', se si e' sicuri che il carattere '\n' non e' nel terminatore e' la cosa migliore da fare ( a parte cambiare "fstream." in <fstream> :p :D ;) ).
Se proprio uno vuole il caso piu' generale invece la cosa migliore penso sia farsi un iteratore apposito da usare con std::search (se a qualcuno interessa, ho provato a farlo e sembra pure funzionare)
Kleidemos
25-04-2003, 16:22
Originally posted by "/\/\@®¢Ø"
sia farsi un iteratore apposito da usare con std::search (se a qualcuno interessa, ho provato a farlo e sembra pure funzionare)
a me!
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void scrivi(string nome, string text)
{
//apro il file in scrittura in appending (si posiziona in fondo al file)
ofstream out(nome.c_str(), ios::app | ios::out);
out << text << "%end";
out.close();
}
//se apri e chiudi tutte le volte il file non ti avanzerà mai e leggerai
//sempre la prima stringa
#define BUFFER_LEN 1024 //dimensione del buffer...può essere cambiata a piacere
//ovviamente se si mette 1 è altamente inefficiente...
//in e text vengono passati per riferimento quindi il loro valore se modificato viene
//cambiato anche nell'ambiente chiamante
//delim è la sequenza di caratteri che delimita le stringhe
bool leggi(ifstream &in, string &text, const char *delim)
{
//data è static perchè può contenere più di una stringa delimitata e di conseguenza
//alla chiamata successiva di leggi il contenuto di data resta quello che c'era alla
//fine della chiamata precedente a leggi
static string data;
char buff[BUFFER_LEN+1]; //buffer di lettura temporaneo
//questo while non termina mai, mi serve per poter gestire il caso in cui la stringa
//contenuta in data non è completa (non è terminata con delim) e di conseguenza ci accodo
//un'altra lettura dal file
while(1)
{
//se data non è vuota
if(data.size() > 0)
{
//trovo la posizione di delim all'interno della stringa
int pos = data.find(delim);
if(pos != string::npos) //se delim c'è in data
{
//text diventa la parte iniziale di data fino a delim
text = data.substr(0, pos);
//prendo da data la parte finale (dalla fine di delim fino alla fine della
//stringa) e lo riassegno a data
data = data.substr(pos+strlen(delim));
//ritorno vero perchè ho trovato un risultato valido (quello in text)
return true;
}
}
if(in.eof()) //se il file è finito
{
text = data; //metto la parte rimanente di data in text
return false; //ritorno falso perchè la lettura è finita
}
//se il file non è finito leggo BUFFER_LEN byte
in.read(buff, BUFFER_LEN);
//metto il carattere di fine stringa in buff,
//gcount rende il numero di byte letti da read, di conseguenza
//indica la fine della stringa
buff[in.gcount()] = '\0';
data += buff; //aggiungo i byte letti a data
}
return false;
}
int main()
{
scrivi("pippo.txt", "ciao");
scrivi("pippo.txt", "ciao2");
ifstream in("pippo.txt"); //apro lo stream in lettura
string text;
while(leggi(in, text, "%end")) cout << text << endl; //leggo text e lo stampo
in.close(); //chiudo lo stream
return 0;
}
Originally posted by "/\/\@®¢Ø"
Se proprio uno vuole il caso piu' generale invece la cosa migliore penso sia farsi un iteratore apposito da usare con std::search (se a qualcuno interessa, ho provato a farlo e sembra pure funzionare)
Butta butta ;)
Kleidemos
25-04-2003, 16:30
tnk cionci!
Cionci,hai perfettamente ragione sull'intero file in una stringa. :)
Pensavo fosse un'esecizio giusto per imparare,in effetti è meglio
impostare gli "apprendisti" nel modo giusto da subito in modo da
non trascinarsi difetti d'impostazione.
Come quelli che ha il "sottoscritto" :D
cia cia.
Ehi Marco !
Pure a me pure a me pure a me
Kleidemos
25-04-2003, 16:43
Originally posted by "verloc"
Pensavo fosse un'esecizio giusto per imparare
Ehi Marco !
Pure a me pure a me pure a me
infatti lo è
/\/\@®¢Ø
25-04-2003, 16:48
L'iteratore che ho scritto e' il seguente
( e' tutt'altro che perfetto... ci sono alcune cose da sistemare ma funziona comunque nel caso che ci serve )
#include <iostream>
#include <iterator>
struct char_stream_iterator
{
typedef std::input_iterator_tag iterator_category;
typedef char value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
char_stream_iterator():stream(0),pos(0)
{}
char_stream_iterator( std::istream& in ):stream(&in),pos(in.tellg())
{}
char operator*()
{ return stream->peek(); }
char_stream_iterator& operator ++()
{
pos = pos + 1;
stream->seekg(pos,ios_base::beg) ;
if ( stream->bad() )
{
stream = 0 ; pos = 0 ;
}
return *this;
}
bool operator == ( const char_stream_iterator& x )
{ return stream == x.stream && pos == x.pos ; }
bool operator != ( const char_stream_iterator& x )
{ return ! ( *this == x ) ; }
std::istream * stream;
unsigned int pos;
};
Nel caso che serve a Kleidemos puo' essere utilizzato cosi':
#include <algorithm>
#include <string>
#include <iostream>
using std::string;
using std::search;
using std::copy;
/* ... */
typedef char_stream_iterator iter;
// trova la posizione dell'iteratore
string term = "%end%";
iter match = search( iter( in ) , iter() , term.begin() , term.end() );
string result;
copy( iter(in) , match , back_inserter( result ) );
// in alternativa si prende match.pos e si sa quanti caratteri leggersi
Sarebbe stato piu' bello poter riutilizzare gli iteratori di stream della libreria, ma non sembra che non sia possibile tenersi un iteratore per riutilizzarlo in un algoritmo successivo.
/\/\@®¢Ø
25-04-2003, 17:04
Ammetto che non e' il massimo della leggibilita' :D ( quindi prima di usarlo controllatelo :p :D), nel nostro caso probabilmente e' pure una complicazione eccessiva. Trovo carino pero' il fatto che utilizzi una sola scansione del testo ( a parte la copia ), per cercare il terminatore. In particolare la lettura di vari spezzoni puo' essere fatta in modo abbastanza "economico" (sia per la memoria, che per le linee da scrivere :D), (nella mia implementazine manca l'operatore di somma che sotto ho utilizzato, ma sono tre righe di codice )
iter first = iter(in);
iter last = iter();
vector< string > data;
while( first != last )
{
iter next = search( first , last , term.begin() , term.end() );
data.push_back( "" );
copy( first , next , back_inserter( data.back() ) );
first = next + term.size(); // Va aggiunto l'operatore di somma !
}
Un'altra semplice soluzione può essere questa:
class ifdstream: public ifstream
{
string delim;
public:
ifdstream(const char *del = "\n"):delim(del) {};
ifdstream &operator >>(string &data)
{
data = "";
while(data.substr((data.size() >= delim.size())?data.size()-delim.size():0).compare(delim.c_str()))
{
data += get();
if(fail())
return *this;
}
data = data.substr(0, data.size()-delim.size());
return *this;
}
};
int main()
{
ifdstream ifd("%end");
ifd.open("pippo.txt");
string text;
while(!ifd.eof())
{
ifd >> text;
cout << text << endl;
}
ifd.close();
return 0;
}
Originally posted by "/\/\@®¢Ø"
Si', se si e' sicuri che il carattere '\n' non e' nel terminatore e' la cosa migliore da fare ( a parte cambiare "fstream." in <fstream> :p :D ;) ).
Se proprio uno vuole il caso piu' generale invece la cosa migliore penso sia farsi un iteratore apposito da usare con std::search (se a qualcuno interessa, ho provato a farlo e sembra pure funzionare)
hai ragione sullo '\n' ; non ci avevo fatto caso
in questo caso uso il codice postato in precedenza :)
oppure un mix:
while( f )
{
getline( f , buf );
if(strstr(buf.c_str(),"%end%")) break;
// .....fai qualcosa d'altro
}
in ambiente BCB scrivere "fstream.h" o <fstream.h> non fa differenza: è un mio errore dovuto all'abitudine
Complimenti Cionci !!!,anche questa è una soluzione bella.
Molto elegante,davvero. :)
E' un tipico esempio di come si dovrebbe programmare in c++ .
Kleidemos
26-04-2003, 11:23
raga voi siete troppo bravi :eek:
non vi raggiungero mai :cry: :cry:
Originally posted by "Kleidemos"
raga voi siete troppo bravi :eek:
non vi raggiungero mai :cry: :cry:
fai il bravo che non è così: non sarebbe la prima volta che l'allievo supera il maestro :)
se hai capito il metodo criptico di marco sei sulla buona strada: iteratori in luogo di "puntatori specializzati" o giù di li
azz... come scrive codice lui sembra di rileggere il vecchio libro sul linguaggio C di Kernigham e Ritchie :D :D :D
Kleidemos
26-04-2003, 19:58
Originally posted by "misterx"
fai il bravo che non è così: non sarebbe la prima volta che l'allievo supera il maestro :)
al tuo livello, a quello di marco o soprattutto a quello di cionci nn arrivero mai :cry:
Se mi perdo in ste semplici cazzate:(
P.S: ma almeno sto esercizio mi è serivto a qualcosa..................spero :D
/\/\@®¢Ø
26-04-2003, 19:59
Originally posted by "Kleidemos"
raga voi siete troppo bravi :eek:
non vi raggiungero mai :cry: :cry:
Io ho cominciato "tardi" a programmare (terzo anno di universita').
Non disperare quindi ;) (eppoi il codice che scrivo io non e' questo granche' ... a leggerlo perlomeno :D ).
Originally posted by "Kleidemos"
al tuo livello, a quello di marco o soprattutto a quello di cionci nn arrivero mai :cry:
Se mi perdo in ste semplici cazzate:(
P.S: ma almeno sto esercizio mi è serivto a qualcosa..................spero :D
se hai passione arrivi, eccome se arrivi....
vabbè va, voglio svelarti un segreto che non tutti ti dicono....
guarda che non devi imparare un linguaggio in tutte le sue sfumature, sarebbe impossibile
nel mondo pratico, quello del lavoro, è sufficiente che impari a risolvere il problema che ti viene posto: in che modo poi lo farai, sono affari tuoi: al propietario dell'azienda non interessa il metodo; a lui interessa solo il risultato ;)
praticamente businness :D
P.S.
io sono più un pratico, quindi meno teorico di marco e cionci ;)
Originally posted by "/\/\@®¢Ø"
Io ho cominciato "tardi" a programmare (terzo anno di universita').
Non disperare quindi ;) (eppoi il codice che scrivo io non e' questo granche' ... a leggerlo perlomeno :D ).
non ti lamentare
quando ho iniziato io, o commodore VIC 20 o aria ;)
Kleidemos
26-04-2003, 20:14
Originally posted by "misterx"
io sono più un pratico, quindi meno teorico di marco e cionci ;)
mi piacie il tuo stile!
Io pero ho 15 anni(1 anno di liceo classico) e mi sembra di aver comenciato troppo tardi :D
E che certe cose nn le capisco subito................poi dopo un po di tempo le capisco:
l'overloading...........letto 5 valte il capitolo, nn ci ho capita na mazza............riletto dopo un quadrimestre di liceo: capito subito :eek:
P.S: bello il tuo prog x le immagini............io nn saprei che pesci pigliare :pig:
Originally posted by "Kleidemos"
mi piacie il tuo stile!
Io pero ho 15 anni(1 anno di liceo classico) e mi sembra di aver comenciato troppo tardi :D
E che certe cose nn le capisco subito................poi dopo un po di tempo le capisco:
l'overloading...........letto 5 valte il capitolo, nn ci ho capita na mazza............riletto dopo un quadrimestre di liceo: capito subito :eek:
P.S: bello il tuo prog x le immagini............io nn saprei che pesci pigliare :pig:
tranquillo, capita a tutti di non cogliere sempre al volo il significato di un qualcosa che ci interessa
ma se ti interessa veramente, prima o poi lo capisci ;)
se poi proprio non ti entra: chiedi qui :D
Kleidemos
26-04-2003, 21:26
Originally posted by "misterx"
tranquillo, capita a tutti di non cogliere sempre al volo il significato di un qualcosa che ci interessa
ma se ti interessa veramente, prima o poi lo capisci ;)
se poi proprio non ti entra: chiedi qui :D
tu come hai imparato il C++???
E il BCB?
Originally posted by "Kleidemos"
tu come hai imparato il C++???
E il BCB?
con tanta pazienza ma soprattutto tanta passione....
a me piace il C ed il C++ in quanto non si è mai finito di imparare....
ognuno poi, ha le sue tecniche, i suoi metodi, le sue illuminazioni; prova ne è tutto il codice completamente differente l'uno dall'altro postato qui dai vari utenti :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.