Newsgroup: it.comp.lang.c++
Titolo: dov'è l'errore?

Ciao a tutti,
perché il seguente programma (in VC++4 per W95) non mi visualizza
correttamente quello che vorrei, cioè:
stringa casuale
stringa casuale
stringa casuale
ecc...?
*** INIZIO CODICE ***
#include <fi1libl2.h>
#include <windows.h>
#include <iostream.h>
#include <math.h>
#include <time.h>
#include <string.h>
#define	CHARACTERS_NUMBER	8
#define	MAX_STRING_LENGTH	20
#define	STRINGS_NUMBER		5
typedef	char*	string;
string generatecharacter(void)
{
	unsigned int	character=floor(rand()*CHARACTERS_NUMBER/RAND_MAX)+1;
	string			c="";
	switch (character)
	{
	case 1:
		c="a";
		break;
	case 2:
		c="b";
		break;
	case 3:
		c="c";
		break;
	case 4:
		c="d";
		break;
	case 5:
		c="e";
		break;
	case 6:
		c="f";
		break;
	case 7:
		c="g";
		break;
	case 8:
		c="h";
		break;
	};
	return(c);
};
string generatestring(void)
{
	unsigned int	stringlength=floor(rand()*MAX_STRING_LENGTH/RAND_MAX)+1;
	string			s="";
	for(unsigned int i=0;i<stringlength;i++)
	{
		strcat(s,generatecharacter());
	}
	return(s);
};
int main(void)
{
	srand((unsigned)time(NULL));	// seme per i numeri casuali
	for (unsigned int j=0;j<STRINGS_NUMBER;j++)
		cout << generatestring() << "\n";
	return(0);
};
*** FINE CODICE ***
Grazie a tutti,
saluti :-)
Marco Zanon (
m.z...@usa.net
)
http://www.geocities.com/SiliconValley/Peaks/6455
(BUY CDS AT THE LOWEST PRICES through my site!!!
Zamorano fan page, free MIDI mailing list, Music db...)

Marco Zanon wrote :
// #include <fi1libl2.h>
#include <windows.h>
#include <stdio.h>							// PARTE 1








		printf( "%s\n", generatestring() );					// PARTE 2
	return(0);
};
NB: Da compilare con il preprocessore del c++.
ciao zec

                 cout << generatestring() << "\n";
Meglio: cout << generatestring() << endl;
Insomma, come puoi vedere, praticamente un disastro. :-)
EMG

 [...]
Quale sarebbe la soluzione che proponi? Io non la vedo...
EMG

 strcat(s,generatecharacter());
Hai posto s, che hai definito come puntatore, all'indirizzo
di un'area di memoria riservata dal compilatore per
mantenere il carattere binario 0; non e` neppure detto
che quell'area sia da te scrivibile (il compilatore potrebbe
benissimo porre quello 0 in un'area dati read-only).  Dopo
di che, con le ripetute strcat, vai a scrivere su quest'area,
e ben oltre di essa, sporcando chissa` quali strutture dati
che "capita" si trovassero da quelle parti.
In C++ standard, e` molto, ma MOLTO meglio, usare vere
stringhe, non queste "pseudostringhe" che sono puntatori
a caratteri e fanno cadere su di te tutta la responsabilita`
di allocare, gestire, liberare la memoria.  Con un
    #include <string>
    using std::string;
invece del tuo typedef, adesso un oggetto di tipo string si
occupa lui di tutta la gestione; e puoi tranquillamente fare
cose del tipo:
    string s;    // inizializzazione automatica
    for(int i=0; i<sl; ++i)
        s += generatecharacter();
eccetera.
Dici che usi VC++4.0, che e` un compilatore assai antico
(la versione attuale e` VC++6) e se ben ricordo non ti
offre la libreria standard (fu introdotta, mi pare, in VC++
4.1 o 4.2).  Il mio consiglio e` di fare un upgrade del tuo
compilatore, o passare al gratuito egcs 1.1.1 se non puoi
permetterti l'upgrade.
Se non vuoi o non puoi seguire questi consigli, dovrai
presumibilmente scriverti tu la tua classe stringa, o
trovarne qualcuna dalla rete.  Certo non puoi limitarti
a fare un "typedef char* string" e operarci con strcat
e soci: qualcuno la memoria deve gestirla.
Alex

 Meglio: cout << generatestring() << endl;
No, non necessariamente meglio.
Il manipolatore endl forza un flush() sullo ostream
dopo avere emesso il carattere di fine-riga; questo
flush() forzato interferisce con la normale gestione
del buffer (streambuf) e puo` peggiorare seriamente
l'efficienza delle operazioni di output.  Se non ci sono
specifiche ragioni di "urgenza" che obbligano a fare si`
che l'output sia visualizzato immediatamente, di solito
e` preferibile emettere un semplice '\n' che non un
endl.  '\n' sara` generalmente preferibile.
Se proprio si vuole cavillare, notiamo che:
    cout << "\n";
e
    cout << '\n';
non sono rigorosamente identiche: la seconda delle
due chiamate (output di un singolo carattere, piuttosto
che di una stringa che "capita" avere lunghezza 1) e`
normalmente piu` efficiente (il compilatore, conoscendo
la semantica della libreria standard, _potrebbe_ in
teoria ottimizzare la prima alla seconda, ma non ne
conosco nessuno che oggi ancora lo faccia).  Per
non sprecare del tutto inutilmente alcuni (pochi)
cicli di macchina, meglio dunque cout<<'\n'.  Non
sono cose molto importanti, ma non c'e` nessun
vantaggio compensativo che possa portare invece a
preferire cout<<"\n".
Alex

 
Niente di particolare una sostituzione della cout con la printf e la
modifica di conseguenza delle include.
Il programma gira, comunque ha ragione Alex.
CIAO ZEC.

 wrote in message
78skn1$n1s$1...@nslave1.tin.it...

 l'efficienza delle operazioni di output.
Bene. Altra cosa a cui non avevo pensato.
Grazie delle correzioni che spero abbiano fatto imparare qualcosa di
nuovo, oltre che a me, anche a qualcuno degli altri partecipanti a
questo newsgroup.
EMG

questo newsgroup.
Prego!  La speranza e` proprio sempre questa -- di aiutare qualcuno
insegnandogli qualcosa.  Grazie a TE, per avere coerentemente
dimostrato, qui come in altre occasioni, di essere sempre cortese,
interessato, e ben disposto -- se tutti gli interlocutori fossero di
carattere, preparazione tecnica, e atteggiamento paragonabili ai
tuoi, questo sarebbe un gruppo a cui sarebbe MOLTO piacevole
partecipare!
Alex

 partecipare!
A parte la "preparazione tecnica", mi riconosco in tutto quanto hai
detto... :-)
EMG

 
Di imparare ce ne e' sempre bisogno, ma perche' la polemica ?
Zec.