Newsgroup: it.comp.lang.c++
Titolo: leggere un file di testo in una string

Approfitto della vostra disponibilità!
Pur non essendo convinto che sia la soluzione migliore, sembra comunque 
la strada più breve per raggiungere il mio obiettivo, con le mie attuali 
competenze.
 
Dovrei leggere un file di testo, inserendolo interamente in una string.
Tale string mi permetterebbe, infatti, di essere passata ad una funzione 
di libreria che ne interpreta il contenuto, e successivamente di essere 
"inviata" su un canale di comunicazione in forma di c-string 
('null-terminated ' char *).
 
Fin'ora sono orientato su una cosa del tipo:
 
   std::string testo;
   std::istream is(filename,ios::in);
   unsigned long length = is.tellg();
   testo.reserve(length);
 
Qui mi blocco. Come faccio a mettere l'intero file nella stringa?
 
Grazie mille!
 
-- 
Mickey

 Qui mi blocco. Come faccio a mettere l'intero file nella stringa?
 
Ovviamente nulla mi vieta di passare per un
 
char *buf = new char[length];
is.read(buf,length);
testo.assign(buf,length);
delete[] buf;
 
Ma possibile che si debba per forza fare il doppio passaggio di memoria?
 
-- 
Mickey

Il 25/01/2012 14:20, Mickey ha scritto:

Forse questa soluzione fa al caso tuo:
 
#include <fstream>
 
void foo()
{
     std::string testo;
     std::ifstream is;
     is.open(filename, std::ios::in );
     is.seekg (0, std::ios::beg);
     is >> testo;
     is.close();
}
 
Maurus
 

Il 25/01/2012 14:20, Mickey ha scritto:

Questa soluzione è la migliore che ho trovato, ma ha ancora il problema 
che nella stringa finale non si hanno i ritorni a capo e quando si hanno 
diversi spazi, vengono compattati in solo uno spazio.
 
 
#include <iostream>
#include <fstream>
 
void foo()
{
     std::string testo;
     std::string parola;
     std::ifstream is;
     is.open("ciccio.txt", std::ios::in );
     is.seekg (0, std::ios::beg);
 
     do
     {
         is >> parola;
         testo += parola;
         testo += " ";
     }
     while (!(is.rdstate() & std::ios::eofbit));
 
     is.close();
}
 
 
Maurus

Il 25/01/2012 14:20, Mickey ha scritto:

La soluzione finale!
 
#include <fstream>
#include <string>
 
void foo(void)
{
     std::string testo;
     std::string linea;
     std::ifstream in("ciccio.txt");
 
     while(std::getline(in, linea))
     {
         testo += linea;
         testo += "\r\n";
     }
 
     // Scommenta la riga finale se vuoi stampare sulla finestra output
     // di visual studio il risultato		
 
     // OutputDebugString(testo.c_str());
}
 
Maurus


   linea += "\r\n";
   testo += linea;
 
vediamo se cogli la differenza ...
 
a parte questo, metterei in cima un'analisi della lunghezza 
totale del file, tanto per non avere sorprese eventuali con 
l'allocazione (metti di ricevere in input un file di 250 MB)
ciao
Soviet



 
Dopo l'analisi della lunghezza del file a quanto dovrei mettere il 
limite per non "sforare" nell'allocazione di memoria della stringa testo?
 
std::string fino a quanto può allocare?
 
 
Maurus
 

 Dovrei leggere un file di testo, inserendolo interamente in una string.
 
Tanto per non lasciarvi sulle spine, vi riporto la mia decisione.
Alla fine ho utilizzato un oggetto CFile delle mfc, con cui ho caricato 
il file in un buffer char*. Questo perché avevo comunque bisogno del 
buffer char* per altri scopi.
 
Mi rimane comunque il dubbio di come poter leggere un file in blocco con 
le librerie standard.
 
-- 
Mickey

 le librerie standard.
 
#include <fstream>
 
int main(int argc,char**argv) {
   std::ifstream F(argv[1]);
   F.seekg(0,std::ios::end);
   std::streampos Size(F.tellg());
   F.seekg(0,std::ios::beg);
   std::string S(Size,0);
   F.read(&*S.begin(),Size);
}
 
 
(Da prendere solo come spunto: manca la gestione degli errori, ecc...)
 
 
  bye
	av.

 }
Per quanto sia molto probabile che questo codice funzioni senza 
problemi, in realtà solo nello standard C++11 è richiesto che lo 
"storage" della classe basic_string sia contiguo, come invece è 
richiesto già nello standard precedente (C++03) per quello della classe 
vector.
 
Ciao.
 


Un modo, anche se sembra che i newline vengano scartati, puo essere:
 
	istream_iterator<char> n;
	istream_iterator<char> iif(f);
	copy(iif,n, back_inserter(s));
 
con f un fstream, s una string
 

 
http://debugfailure.wordpress.com/2009/11/20/is-stdstrings-storage-contiguous/
 
 
Poi non so...
 
  bye
	av.

 a sto punto conviene andare di malloc :-)
 
Mai! :-)
Preferisco sempre un vector, se non altro per RAII.
 
 
  bye
	av.

 av.
 

 Qui mi blocco. Come faccio a mettere l'intero file nella stringa?
 
Il modo più semplice ed efficiente di leggere un file binario è usare un 
memory-mapped-file, che pero' non fa parte dello standard.
A tale scopo, ho scritto una libreria per Windows e Linux che puoi 
scaricare da qui:
http://sourceforge.net/projects/cppbolts/
 
 
Per creare il memory-mapped file basta scrivere:
     input_memory_file mf(filepath);
     if (! mf.data()) return false;
e poi, per ottenere la string:
     string s;
     s.assign(mf.data(), mf.size());
oppure:
     string(mf.data(), mf.size());
 
-- 
 
Carlo Milanesi
http://carlomilanesi.wordpress.com/
 

 string.
 
Sì, in realtà quello di cui ho bisogno è un stringstream, nel senso che 
devo passare il contenuto del file ad una funzione che accetta quel tipo 
di parametro.
 
Ora magari mi maledirete, perché esiste un metodo più immediato per 
riversare il contenuto di un file in un oggetto stringstream...
 
-- 
Mickey


l' avevo gia postato, forse non l' ha capita nessuno
riposto:
   istream_iterator<char> n;
     istream_iterator<char> iif(f);
     copy(iif,n, back_inserter(s));
 
con f un fstream, s una string
 
alla fine in s ha il contenuto di un file
unica indicazione, sembra che i newline non vengano copiati