Newsgroup: it.comp.lang.c++
Titolo: Problema con std::string

Sto modificando un parser di un 'mini-interprete' che utilizzava per le 
stringhe la CString MFC.
Il problema è che la CString possiede un metodo Format il quale è un 
wrapper di sprintf. In pratica str.Format("Il numero è %ld",3) mi ritorna 
'Il numero è 3' in str.
Dato che la stringa di formattazione "Il numero è %ld" è non modificabile 
nei programmini che vengono interpretati come posso evitare di usare 
questo tipo di codice:
....
char Str[4096];
std::string FormatStr=<QUELLO LETTO DAL FILE>;
sprintf(Str,FormatStr.c_str(),Value);
Cioè evitare di usare un array di char di dimensione fissa che non mi 
garantisce che il risultato della sprintf sia interamente contenuto.
Il tutto se possibile usando std::string per la stringa 'finale'.
Grazie!
-- 
Luc.

Luc <XXX...@katamail.comXXX> writes:

snprintf e' standard C99, e permette di scrivere 'alla sprintf' fino
ad un massimo di N caratteri, dove N e' una delle variabili di
chiamata.  Non so se sia standard anche C++, ma vale comunque la pena
di guardare se il tuo compilatore la accetta.
Altrimenti, prima di C99, i programmatori C prima scrivevano la string
con fprintf su /dev/null (non so quale sia l'equivalente Microsoft -
si tratta di un file/device inesistente che ingoia i bytes e, secondo
la leggenda, li teleporta in un'altra dimensione dove vivono felici);
fprintf restituisce il numero di caratteri scritti; se e' maggiore
della lunghezza del buffer si ritorna errore (settando errno a
EMSGSIZE, magari); se no, si usa sprintf essendo sicuri di non fare
casino.  Un po' involuto, ma che vuoi fare?
-- 
Maurizio Loreti  - Linux Is Not UniX -  
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

la leggenda, li teleporta in un'altra dimensione dove vivono felici);
NUL, ma non è una soluzione molto portabile.
-- 
Marco Barisione (ICQ 84277092)

 di guardare se il tuo compilatore la accetta.
Ok, c'è. Ma non mi dice di quanto avrei 'sforato' per permettermi di 
riallocare il buffer. Non posso perdere tempo in tentativi, essendo un 
interprete... 8(
-- 
Luc.

 garantisce che il risultato della sprintf sia interamente contenuto.
Il codice da me suggerito usa un array che viene allocato
dinamicamente: e' della dimensione giusta e viene eliminato subito
dopo l'operazione.
Ciao
---
Riccardo

 dopo l'operazione.
Ed esploderà al primo utilizzo. Indovina perche? 8) 
-- 
Luc.

> Ed esploderà al primo utilizzo. Indovina perche? 8)
Non lo so. Io l'ho compilato e funziona.
Questo e' il codice completo della mia prova
#include <iostream>
int main()
{
	char* buffer;
	int Value=1;
	const char* LETTO_DAL_FILE = "numero %d";
	std::string FormatStr = LETTO_DAL_FILE;
	buffer = new char[FormatStr.size()+1];
	sprintf(buffer, FormatStr.c_str(),Value);
	std::string result=buffer;
	delete[] buffer;
	std::cout << result.c_str() << std::endl;
	return 0;
}
---
Riccardo

 [CUT]
Prova a mettere Value=1234567 per esempio...
-- 
Luc.

>la leggenda, li teleporta in un'altra dimensione dove vivono felici);
Quest'ultima non la sapevo proprio..:-)
P.
-- 
   	 ___      ___  __       ___       ___ ___  ___
	/__/ /	 /__/ /   //_/ /__  /__/ /__ /__  /__/
       /__/ /__ /  / /__ // / ___/ /  / /__ /__  /
 
 
http://theunixplace.com/~entropia/index.html
 
Obviously welcome removing Anti-spam filters to contact me in email :-)

 Quest'ultima non la sapevo proprio..:-)
Mai usato Amiga? 8)
-- 
Luc.

...

Hai ragione, ma comunque basta mettere 
new char[FormatStr.size()+costante]
se i valori sono interi o double
oppure
new char[FormatStr.size()+strlen(Value)+costante]
se i valori sono stringhe.
Alternativamente costruisci un parser che copia strFormat in uno
stringstream finche' trova il carattere %, a quel punto fa uno switch
a seconda del carattere successivo al % e copia Value nello
stringstream, poi riprende a copiare strFormat fino alla fine o al
successivo %, ecc...
---
Riccardo

 successivo %, ecc...
Il mio era solo un esempio. Il discorso deve essere valido per QUALUNQUE 
FormatString!
-- 
Luc.

 nsize, then only nsize characters are written, with no terminating
'\0' character.
If nsize is 0, then the string will not be written to (and may be NULL).
^^^^^^^^^^^^^^^^
Return Value
Number of bytes output, or,
if nsize is 0, the number of bytes needed, not including the terminating
^^^^^^^^^^^^^^^
'\0' character.
ciao
Massimo

 parametro 0 ti restituisce il numero di bytes che servono meno 1.
Questo invece è quello che VC++ dice su _snprintf():
If the number of bytes required to store the data exceeds count, then 
count bytes of data are stored in buffer and a negative value is 
returned.
-- 
Luc.

"Luc" ha scritto
: Massimo Valentini ha scritto...

:
E allora se la dimensione iniziale non e` sufficiente devi raddoppiare
fino a che raggiungi una dimensione sufficiente..., partendo da una
dimensione ragionevole dovrebbe capitare di rado.
Comunque ho letto la man page del gcc e pare che sia lo std C99
a prevedere che se lo spazio non e` sufficiente, il valore
restituito debba indicare la dimensione necessaria, senza il NULL.
ciao
Massimo

Il tutto se possibile usando std::string per la stringa 'finale'.
Ogni tanto capita di accorgersi che le MFC non sono proprio un
capolavoro di design. Sono il frutto di un compromesso, ovvero quello
di dover creare un framework ad oggetti che perň non scontentasse
troppo i vecchi programmatori che utilizzavano il C e le api di
Windows, ed é per questo che utilizzano tecniche osbolete.
Tutte le volte che ho usato MFC mi sono sempre creato delle classi
derivate da quelle fornite dalla libreria fornendo nuovi metodi che
nascondessero le "vergogne" della libreria originale, in questo modo
ho reso alcune cose piů usabili per i miei programmi ma ho dovuto
necessariamente perdere piů tempo.
Il Ghenio
---------
// TODO: Place your ass here

 [CUT]
Beh, nel mio caso è il contrario! La CString.Format non ha equivalenti in 
std::string!
Per il resto (nascondere gli orrori MFC derivando TUTTO), è solo 
demagogia informatica... 8)
-- 
Luc.


No... non sono utente cpu da molti anni. Mi "contento" delle esperienze
su Linux.... 8-)
