char* zu float



  • ich bin grad dabei mit einen eigenen Parser zu basteln. Das parsen von den Zahlen selbst ist noch überhaupt nicht implementiert. Muss ich das auch noch selbst machen, oder gibts da schon was fertiges.



  • std::stringstream kann das.



  • David_pb schrieb:

    std::stringstream kann das.

    Und zwar so:

    template <typename To, typename From>
    bool try_lexical_cast(From const& from, To* to)
    {
        std::stringstream interpreter;
        return interpreter << from and interpreter >> *to and interpreter.eof();
    }
    
    struct invalid_cast : std::logic_error {
        invalid_cast() : std::logic_error("Invalid cast.") { }
    };
    
    template <typename To, typename From>
    To lexical_cast(From const& from)
    {
        To ret;
        if (not try_lexical_cast(from, &ret))
            throw invalid_cast();
        return ret;
    }
    

    Es gibt noch allgemeinere Implementierungen (Parametrisierung des Interpreters) aber ich denke, die hier ist schon ganz in Ordnung).



  • Oder so:

    template <typename To, typename From> 
    bool try_lexical_cast(From const& from, To& to) 
    { 
        std::stringstream interpreter; 
        return interpreter << from && interpreter >> to && ( interpreter >> std::ws ).eof(); 
    } 
    
    struct invalid_cast : std::logic_error { 
        invalid_cast() : std::logic_error("Invalid cast.") { } 
    }; 
    
    template <typename To, typename From> 
    To lexical_cast(From const& from) 
    { 
        To ret; 
        if (!try_lexical_cast(from, ret)) 
            throw invalid_cast(); 
        return ret; 
    }
    

    Oder so:

    template <typename To, typename From> 
    To lexical_cast(From const& from) 
    { 
    	std::stringstream cnv;
    	To tmp;
    
    	if ( !( cnv << from && cnv >> tmp && ( cnv >> std::ws ).eof() ) )
    		throw std::logic_error( "lexical_cast failed" );
    
    	return tmp;
    }
    

    Oder so:

    float x = boost::lexical_cast< float >( "3.1415" );
    


  • ich hab mich mal an google gewendet (hätte ich vorher machen sollen), und

    float atof(char*);
    

    gefunden, ich denke das passt für meine bedürfnisse besser, als so was langes wie das mit den stringstreams. Das ist vor allem kurz.

    Edit:
    das letzte sieht auch nicht schlecht aus, vor allem, weil es ein einzeiler ist.



  • Dafür sind stringstream's weitaus flexibler einzusetzen 😉 (mit den lexical_cast's dort oben kannst du alles konvertieren, was die Stream-Operatoren überladen hat, atof() ist speziell für eine mögliche Umwandlung ausgelegt - und obendrein noch ein Erbe aus C, was manchen C++lern Unbehagen bereitet)

    PS: Hättest du erst die FAQ gelesen, wärst du schneller zum Ziel gekommen 😉



  • template <typename To, typename From> 
     To lexical_cast(From const& from) 
     { 
         std::stringstream cnv; 
         To tmp; 
    
         if ( !( cnv << from && cnv >> tmp && ( cnv >> std::ws ).eof() ) ) 
             throw std::logic_error( "lexical_cast failed" ); 
    
         return tmp; 
     }
    
    int main()
    {
        float x = lexical_cast< float >( "3.1415" );
    }
    

    Die andren sind auch Einzeiler wenn man sie verwendet... 🙄


Anmelden zum Antworten