Newsgroup: it.comp.lang.c++
Titolo: intero->stringa

A me serve l'esatto contrario di cio' che e' stato
richiesto un paio di messaggi fa:
esistono in C++ metodi o funzioni per trasformare un
intero i = 123 nella corrispondente stringa "123" ?
grazie mille e scusate della banalita' della domanda
Matteo

Ti rispondo facendoti notare che il 4 luglio è stata posta la stessa
domanda, lo so perchè anche a me serviva la stessa conversione.
ho usato std::ostringstream, e poi si sfrutta la sua ridefinizione
dell'operatore <<.
Quindi :
std::ostringstream oss;
oss << n		(n è l'intero)
oss.str();	restituisce la stringa.
L'ho usata copiandola pari pari, ma non sono troppo sicura di avere
capito bene quello che fa, in pratica credo che sia come associare il
flusso di caratteri ad una stringa, invece che per esempio allo standard
out..Correggetemi se sbaglio e soprattutto ditemi se poi con questo
flusso che ho aperto ci devo fare qualcosa, tipo chiuderlo!
	più che rispondere per l'ennesima volta domando.
ciao Veruska


 flusso che ho aperto ci devo fare qualcosa, tipo chiuderlo!
No, niente, basta distruggerlo (in questo caso č una variabile automatica e
si distrugge, appunto, automaticamente).
Ciao.

 intero i = 123 nella corrispondente stringa "123" ?
Eccoti un esempio:
#include <iostream>
#include <string>
#include <sstream>
void IntToString( std::string &s, int n )
{
    std::ostringstream oss;
    oss << n;
    s.swap( oss.str() );
}
std::string IntToString2( int n )
{
    std::ostringstream oss;
    oss << n;
    return oss.str();
}
int main()
{
    int n = 12345;
    std::string s;
    IntToString( s, n );
    std::cout << s << std::endl;
    std::cout << IntToString2( n ) << std::endl;
}
EMG

 flusso che ho aperto ci devo fare qualcosa, tipo chiuderlo!
No, non serve. E non servirebbe, grazie al distruttore, neanche per un
fstream.
EMG

quanto č poco "elegante"!
Sono perfettamente d'accordo.
Inoltre non c'e' di mezzo solo la copia, ma anche l'allocazione del
buffer per l'oggetto string e il rilascio del buffer di ostringstream.
"Piccole cose", ma in alcuni contesti possono risultare
inaccettabili. - si pensi ad applicazioni real-time dove ogni 'new' va
attentamente ponderata.
Io conosco ancora troppo poco la libreria standard e, fino a che non
avro' trovato un approccio migliore, * dovro' * usare uno "stile C"
per risolvere queste problematiche.
Ho trovato nel sito
http://www.icce.rug.nl/docs/cplusplus/cplusplus.html
 esempi di
utilizzo di una classe "ostrstream" che puo' inviare caratteri in
perfetto stile "ostream" ad un buffer passatogli attraverso il
costruttore:
char buffer[10];
ostrstream str(buffer, 10);
str << 123;
Non sono riuscito a compilarlo: ostrstream e' un tipo sconosciuto.
Eppure in quel sito questa classe viene presentata come parte di C++
I/O library.
  Paolo G.

 }
Il gcc 2.95.2 dice che non si puo' passare un temporaneo come
parametro a una funzione che prende un non-const reference (e
che quindi potrebbe modificare il temporaneo):
prova.c: In function `void IntToString(std::string &, int)':
prova.c:10: initialization of non-const reference type `class std::string &'
prova.c:10: from rvalue of type `std::string'
....:    in passing argument 1 of `std::string::swap(std::string &)'
e penso che il gcc abbia ragione.
Come soluzione si puo' scambiare il ruolo di s e oss.str():
    oss.str().swap( s );
Questo compila perfettamente.  Pare infatti che, mentre passare
un temporaneo a una funzione che lo modifica sia considerato
pericoloso [1], chiamare un metodo non-const del temporaneo sia
invece sicuro.
Di questa asimmetria si sta discutendo su comp.std.c++; una delle
soluzioni proposte e' quella di proibire l'inizializzazione dei
non-const reference con temporanei solo quando il temporaneo e'
generato implicitamente dal compilatore (negli altri casi si
spera che il programmatore sappia quello che sta facendo).
[1] Le modifiche fatte sul temporaneo vanno perse, e questo puo'
essere causa di errori subdoli, soprattutto se il temporaneo e'
creato implicitamente dal compilatore.
Esempio:
  void incr( int & i )  { ++i; }
  ...
  char ch = 0;
  incr( ch );   // errore
Chiamando la funzione verrebbe creato (e incrementato) un 
temporaneo, mentre ch rimarrebbe al suo valore originale.
	Mauro

 I/O library.
Evidentemente è un sito un po' arretrato. :-)
EMG

 temporaneo, mentre ch rimarrebbe al suo valore originale.
Vero. Infatti il Borland C++ 5.5 in questo caso avvisa.
EMG

 Versione vecchia? Eppure dovrebbe essere l'ultima.
Ho un po' semplificato il messaggio di errore.  Nel messaggio
originale al posto di std::string c'era il nome completo:
std::basic_string<char,std::char_traits<char>,std::allocator<char> >
Sarebbe bello che il compilatore facesse automaticamente
questa semplificazione (anche per i/ostream, map, ...).
Il Comeau C++ (disponibile per compilazione online all'indirizzo
http://www.comeaucomputing.com/tryitout/
) fornisce un messaggio
molto piu' semplice (evitando di nominare tipi e funzioni):
"27557.c", line 9: error: initial value of reference to non-const must be an
          lvalue
    s.swap( oss.str() );
            ^
E fornisce anche la freccietta che (con un font fisso) indica
il punto esatto dell'errore.
Non so se i messaggi del Comeau C++ siano sempre chiari oppure
questo era un caso (e' la prima volta che lo provo).
	Mauro

 e penso che il gcc abbia ragione.
E' un warning o un errore? Normalmente passare un temporaneo al posto di un
"non-const reference" può provocare subdoli errori, ma in questo caso (non sono
andato a vedere il codice, però) si scambiano soltanto i puntatori al buffer e
quindi quando si distrugge l'oggetto temporaneo viene distrutto il buffer che
era di s; ad s invece adesso appartiere il buffer dell'oggetto temporaneo, che
verrà poi distrutto assieme ad s: nessun problema dunque.
Ciao FBF.

attentamente ponderata.
Ok, pero` nella maggior parte delle applicazioni questo non e` un
problema e comunque ottimizzare a priori puo` essere controproducente.
Meglio aspettare di sapere oggettivamente quali saranno le porzioni
di codice critico.
Paolo

 nessun problema dunque.
In questo caso non ci sono problemi, ma il compilatore non
puo' sapere che a noi del vecchio valore di s (passato poi
al temporaneo) non ce ne frega niente.
	Mauro

 un temporaneo.
Beh, basta fare:
std::string temp = oss.str();
s.swap(temp);
un compilatore un po evoluto non chiamerà il costruttore di copia e a questo punto
il codice si comporta come prima, ma e' standard.
Ciao Fbf