Risultati imprevisti utilizzando istringstream per la doppia conversione da stringa a stringa in C++

StackOverflow https://stackoverflow.com/questions/1698265

Domanda

Attualmente sto provando a prendere una stringa ("0.1") e convertirla in un double utilizzando C++ in Xcode su 10.6 con gcc4.2.

Sto usando una funzione da cui ho pizzicato un'altra domanda, ma quando provo a utilizzare la funzione, il mio input secondo gdb è (string)"0.1", ma il mio output è (double)2.1220023981051542e-314.

Ecco il mio snippet copiato direttamente dal codice:

double strToDouble(std::string const &numberString)
{
    istringstream inStream(numberString);
    double doubleValue;
    inStream >> doubleValue;
    if(!(inStream && (inStream >> std::ws).eof()))
    {
        return 0.0;  
    }

    return doubleValue;
};

Sto usando C++ anziché Obj-C, poiché probabilmente alla fine dovrà essere compilato su un computer *nix o Windows.

Sono naturalmente un programmatore PHP, ma ho bisogno di accelerare alcuni numeri, quindi lo sto facendo in un linguaggio compilato.È passato molto tempo dall'ultima volta che l'Università si è occupata di una lingua di livello inferiore =P.Quindi, se qualcuno avesse qualche idea, sarebbe molto apprezzata...

Drew J.Sonne.

Codice completo:

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

/*
 * @var delimiters the string to define a break by
 * @var str the string to break
 * @var tokens where to store the broken string parts.
 */
void explode(const string& delimiters, const string& str, vector<string>& tokens)
{
    // Skip delimiters at beginning.
    string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    // Find first "non-delimiter".
    string::size_type pos     = str.find_first_of(delimiters, lastPos);

    while (string::npos != pos || string::npos != lastPos)
    {
        // Found a token, add it to the vector.
        tokens.push_back(str.substr(lastPos, pos - lastPos));
        // Skip delimiters.  Note the "not_of"
        lastPos = str.find_first_not_of(delimiters, pos);
        // Find next "non-delimiter"
        pos = str.find_first_of(delimiters, lastPos);
    }
};

/*
 * @var numberString double to be converted as a string.
 */
double strToDouble(std::string const &numberString)
{
    istringstream inStream(numberString);
    double doubleValue;
    inStream >> doubleValue;
    if(!(inStream && (inStream >> std::ws).eof()))
    {
        return 0.0;  
    }

    return doubleValue;
};

class Cluster {
private:
    vector<double> latStore;
    vector<double> lngStore;
public:
    Cluster(int,string,string);
};

/*
 * @var latString a comma seperated list of doubles for the latitudes.
 * @var lngString a comma separated list of doubles for the longitudes.
 */
Cluster::Cluster(int newLocationLength, string latString, string lngString)
{
    // mark our vectors
    vector<string> latStoreString;
    vector<string> lngStoreString;

    // Explode our input strings.
    explode(",", latString, latStoreString);
    explode(",", lngString, lngStoreString);

    for( int i = 0; i < latStoreString.size(); i++)
    {
        // Grab the latitude and store it.
        string tempLat = latStoreString[i];
        double latDouble = strToDouble(tempLat);
        latStore.push_back( strToDouble(tempLat) );

        // Grab the longitude and store it.
        string tempLng = lngStoreString[i];
        lngStore.push_back( strToDouble(tempLng) );
    }
}

int main (int argc, char * const argv[]) {

    Cluster *rect = new Cluster("0.1,0.4","0.1,0.4");

    return 0;
}
È stato utile?

Soluzione

Questo potrebbe essere causato da modalità STL debug. Rimuovere le macro _GLIBCXX_DEBUG in ambiente di compilazione preprocessore macro del bersaglio.

C ++ Debug costruisce rotto in Snow Leopard X-Code

Altri suggerimenti

Perché non usare atof (), invece? link

Non vedo nulla di sbagliato nel tuo frammento di codice.Puoi mostrare il codice che stai utilizzando produzione il risultato

Come suggerito Myles, atof () potrebbe essere più semplice. È possibile convertire un oggetto stringa in una stringa c chiamando la funzione membro c_str ():

double result = atof(inputString.c_str()); // 0.0 if a double couldn't be read

Ecco qualche informazione in più: http://www.cplusplus.com/reference / clibrary / cstdlib / atof /

#include <iostream>
#include <sstream>

double strToDouble(std::string const &numberString)
{
    std::istringstream inStream(numberString);
    double doubleValue;
    std::cout << doubleValue << '\n';
    inStream >> doubleValue;
    if(!(inStream && (inStream >> std::ws).eof()))
    {
        return 0.0;  
    }

    return doubleValue;
};

int main()
{
    std::cout << strToDouble("0.1") << '\n';

    return 0;
}

Il codice di cui sopra mi dà il seguente risultato:
    -2.36907e-39
    0.1

Sei per caso controllando il valore di doubleValue prima di tornare?


Cluster::Cluster(string latString, string lngString)
{
    // mark our vectors
    vector<string> latStoreString;
    vector<string> lngStoreString;

    // Explode our input strings.
    explode(",", latString, latStoreString);
    explode(",", lngString, lngStoreString);

    for( int i = 0; i < latStoreString.size(); i++)
    {
        // Grab the latitude and store it.
        string tempLat = latStoreString[i];
        std::cout << "tempLat=" << tempLat << '\n';
        double latDouble = strToDouble(tempLat);
        std::cout << "latDouble=" << latDouble << '\n';
        latStore.push_back( strToDouble(tempLat) );

        // Grab the longitude and store it.
        string tempLng = lngStoreString[i];
        lngStore.push_back( strToDouble(tempLng) );
    }
}

int main (int argc, char * const argv[]) {

    Cluster *rect = new Cluster("0.1,0.4","0.1,0.4");

    return 0;
}

Output:
    Templat = 0.1
    latDouble = 0.1
    Templat = 0.4
    latDouble = 0.4

È possibile eseguire il codice con queste modifiche (che non stava utilizzando il parametro int nel ctor, quindi ho solo tolto). Ho anche eseguito il codice utilizzando valgrind senza errori (solo perdite di memoria).

Sembra che tu non ha ottenuto risposta al tuo problema implemetion. Altri hanno suggerito di utilizzare atof (). Se volete risolvere il problema nella vostra L'implementazione, allora non guardare il codice qui sotto. Invece di dover vettore di esplodere metodo, messo vettore per evitare codice ridondante. Ho cambiato il codice in strToDouble pure.

void explode(const string& delimiters, const string& str, vector<double>& tokens)
{    
     // Skip delimiters at beginning.   
     string::size_type lastPos = str.find_first_not_of(delimiters, 0);   
     // Find first "non-delimiter".    
     string::size_type pos = str.find_first_of(delimiters, lastPos);
     while (string::npos != pos || string::npos != lastPos)   
     {        
              // Found a token, add it to the vector.       
             string temp = str.substr(lastPos, pos - lastPos);
             tokens.push_back(strToDouble(temp));    
             // Skip delimiters.  Note the "not_of"        
            lastPos = str.find_first_not_of(delimiters, pos);        
            // Find next "non-delimiter"        
            pos = str.find_first_of(delimiters, lastPos);    
     }
}

double strToDouble(std::string const &numberString)
{  
   istringstream inStream(numberString);    
   int pos = numberString.find_first_not_of("1234567890.", 0);

   if (string::npos != pos)
   {
       return 0.0;
   }
   else
   {
      double doubleValue;   
      inStream >> doubleValue;        
      return doubleValue;
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top