Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16

Discussione: [c++] inttostr

  1. #1

    [c++] inttostr

    ciao a tutti! volevo fare una funzione per convertire da intero a stringa un numero ovviamente.
    ho così scritto la funzione che reputavo facile( e che mi sembra ancora adesso ) ma ottengo non un errore ma una cifra diminuita di uno o altre imprecisioni per alcuni numeri.. poi varia da numero a numero quindi...
    eccola:

    ps.: la funzione lun_str() restituisce la lunghezza della stringa.. e ho gia verificato che è giusta
    sono consapevole che quella che ho scritto non sia una delle piu efficienti, pero per quello che devo fare va bene lo stesso... e ho preferito non usare puntatori e altro perche volevo farla abbastanza velocemente...
    codice:
    string inttostr( int n )
    {
    	string s= "";
    	string temp= "";
            float nd;
    	
    	while ( n >= 10 )
    	{
    		nd= n / 10.0;
    		n= n / 10;
    			
    		s= s + ( (char) ( ( nd -  n ) * 10.0 + 48 ) );
    	}  
    	
    	if ( n < 10)
    	  s= s + ( (char) (n + 48) );
    	  
    	temp= s;  
    	
    	if ( lun_str( s ) > 1 )
    	  for ( int i= lun_str( s ) - 1; i >= 0; i-- )
    	    s[i]= temp[lun_str( s ) - i - 1];
    	  	
    	return s;
    }

    per favore dateci un occhiata
    grazie in anticipo

  2. #2
    Mi pare che tu ti stia complicando inutilmente la vita, per diversi motivi:
    - per ottenere il resto della divisione intera non c'è bisogno di fare tutto quel bailamme con i float, basta usare l'operatore modulo; è da qui che vengono i tuoi errori di precisione che dici, dato che i float hanno precisione limitata e per questo spesso si ottiene un risultato non esatto sulle divisioni per 10 (le uniche divisioni che danno risultati esatti con i float e i double sono quelle per potenze di due);
    - per ottenere la lunghezza della stringa basta s.size(); (e se nella tua lun_str conti i caratteri finché non trovi uno 0 - come nelle stringhe C - stai facendo un errore);
    - non c'è bisogno di riportare i codici ASCII come numeri (cosa che peraltro rende il tuo programma potenzialmente non portabile, ma soprattutto poco leggibile), puoi specificare literal di tipo char semplicemente mettendo il carattere che ti interessa tra apici singoli - quindi, non scrivere 48 ma '0';
    - per invertire la stringa, basta usare l'algoritmo reverse dall'header <algorithm>.

    Ergo, il tuo codice (con in aggiunta il supporto ai numeri negativi) diventa:
    codice:
    #include <algorithm>
    #include <string>
    
    std::string inttostr(int n)
    {
        // Caso speciale: n=0
        if(n==0)
            return "0";
        // Stringa da restituire
        std::string ret;
        // Se il valore è negativo, se lo segna e per il resto dell'algoritmo considera il valore assoluto
        bool minus=n<0;
        if(minus)
            n=-n;
        // Ad ogni iterazione attacca in fondo alla stringa il resto della divisione intera per 10, e divide per
        // 10 n
        for(;n;n/=10)
            ret+=(n%10)+'0';
        // Se il numero era negativo, attacca in fondo il meno
        if(minus)
            ret+='-';
        // Inverte la stringa
        std::reverse(ret.begin(), ret.end());
        return ret;
    }
    Ma tutto sommato la maniera più semplice per scrivere del codice del genere sarebbe usare semplicemente le funzionalità che il C++ già mette a disposizione:
    codice:
    #include <sstream>
    #include <string>
    
    std::string inttostr(int n)
    {
        std::ostream os;
        os<<n;
        return os.str();
    }

    P.S.: il codice va specificato tra tag [CODE] ... [/CODE], altrimenti perde l'indentazione; qui ho corretto io, in futuro ricordatene.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    I float sono soggetti al round error cioè perdono un po' di precisione via via che si eseguono calcoli. Per esempio 0.1 + 0.1 ... (per 10 volte) non farà 1 ma 0.9999999.

    Per cui conviene evitare di usare nd.
    La soluzione è molto semplice: nd viene usato per calcolare il resto tra n e 10 ma basterebbe usare l'operatore modulo (%)! Inoltre la condizione del while è leggermente sbagliata, in quanto basterebbe che n > 0 perché il resto funziona anche con numeri compresi tra 0 e 9.

    Ho scritto questo un po' di tempo fa, dovrebbe funzionare.

    codice:
    string int_to_str( int n )
    {
        if(!n)
            return "0";
    
        string s;
        string tmp;
    
        while ( n > 0 )
        {
            s += n % 10 + 48;
            n /= 10;
        }
    
        tmp = s;
    
        for (int i = s.size() - 1; i >= 0; i-- )
            s[i]= tmp[s.size() - i - 1];
    
        return s;
    }
    Edit: mi hanno preceduto

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Se il compilatore la supporta (conforme al C++11) c'è anche std::to_string().

    http://en.cppreference.com/w/cpp/str...ring/to_string
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    grazie veramente a tutti quelli che mi hanno risposto, molto gentili! e complimenti per il vostro "bagaglio" da programmatori

    effettivamente quando ho scritto questa funzione non so cosa mi passava per la testa per non aver utilizzato l'operatore modulo, tanto che in un abbozzo di funzione l'ho utilizzato ma poi chissà come l' ho tradotto in c++ poi.

    a proposito dei float non immaginavo assolutamente che si potesse verificare una situazione simile

    per il resto grazie ancora infinitamente di tutte le spiegazioni esaurienti e consigli che mi avete dato

    ps: mitaly scusami per la non indentazione

    grazie ancora ! ciao a tutti

  6. #6
    a proposito scusate ancora ma mi piacerebbe avere da voi una veloce spiegazione sulle string:
    mitaly mi hai detto che c'è una differenza tra le string del c++ e quelle del c.

    di quello che so una stringa si può trattare come un vettore di caratteri il cui carattere terminante è '/0'.

    nel c sono le char s[];
    nel c++ hanno creato un nuovo tipo string( che è dinamico rispetto al vettore del c )

    ma perchè sostieni che le string del c++ sono diverse da quelle del c anche per il carattere terminatore?

    sono anche ben accettate ( anzi con gran piacere ) le risposte di altri utenti

    grazie in anticipo

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Le stringhe del C++ sono oggetti (la string è una classe)

    http://en.wikipedia.org/wiki/String_(C%2B%2B)
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  8. #8
    Originariamente inviato da maluz1
    ma perchè sostieni che le string del c++ sono diverse da quelle del c anche per il carattere terminatore?
    Perché è così. Le stringhe C sono dei semplici array di caratteri, la cui lunghezza non è nota a priori (bisogna andarsi a cercare il carattere di terminazione); std::string invece è una classe, che, tra le altre cose, si tira dietro separatamente la lunghezza dell'array di char incapsula (ovvero, le std::string sono un tipo di counted string), motivo per cui il carattere di terminazione non ha alcun significato particolare (anzi, in una stringa C++ puoi inserire quanti caratteri di terminazione ti pare anche in mezzo alla stringa, senza che questo ne cambi la lunghezza).

    In generale quindi se stai lavorando con std::string lascia perdere le funzioni stile C di gestione delle stringhe (strlen, strcmp, ...) e usa invece i metodi di std::string (size(), gli operatori relazionali, ...).

    Ti raccomando inoltre di dare una ripassata al tuo manuale di C++ - la distinzione tra std::string e stringhe C è abbastanza fondamentale.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    io sto imparando il c++ da alcuni videocorsi su youtube ma non sono ancora arrivato alle classi e oop( anche se so di cosa si tratta siccome l' ho studiata in pascal ), mi avete fatto ricordare che la string è una classe ma non sapevo proprio di questa fondamentale distinzione...

    grazie mille del vostro aiuto! ciao a tutti!

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da maluz1
    io sto imparando il c++ da alcuni videocorsi su youtube
    Secondo me questo è il problema.

    C++ è un linguaggio complesso (e l'OOP non è banale).

    Studia dai libri e con tanta pazienza. Non ci sono scorciatoie se vuoi fare bene.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.