نتائج غير متوقعة باستخدام istringStream للحصول على سلسلة لتحويل مزدوج في C ++

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

سؤال

أحاول حاليا التقاط سلسلة ("0.1") وتحويله إلى مزدوج باستخدام C ++ في Xcode على 10.6 مع GCC4.2.

أنا أستخدم وظيفة أنا معروض من سؤال آخر, ، ولكن عندما أحاول استخدام الوظيفة، فإن إدخالي وفقا ل GDB هو (سلسلة) "0.1"، ولكن الإخراج الخاص بي هو (مزدوج) 2.1220023981051542E-314.

هنا هو مقتفي نسخ مباشرة رمز:

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

    return doubleValue;
};

أنا أستخدم C ++ بدلا من OBJ-C، لأنه من المحتمل أن يتم تجميعه على جهاز * Nix أو Windows في نهاية المطاف.

أنا بطبيعة الحال مبرمج PHP، ولكن لديك بعض الأرقام الطحن أحتاج إلى تسريع، لذلك أنا أفعل ذلك بلغة مترجمة. لقد مضى وقت طويل منذ التعامل الجامعي بلغة أقل المستوى = ص. لذلك، إذا كان لدى أي شخص أفكارا، فسيكون موضع تقدير كبير ...

درو ج. سون.

رمز كامل:

#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;
}
هل كانت مفيدة؟

المحلول

قد يكون سبب هذا وضع تصحيح STL. قم بإزالة وحدات ماكرو _glibcxx_debug في إعداد Build Preprocessor Preprocessor الخاص بك.

C ++ Debug Builds كسر في سنو ليوبارد X-Code

نصائح أخرى

لماذا لا تستخدم atof () بدلا من ذلك؟ حلقة الوصل

لا أستطيع أن أرى شيئا خاطئا في شظية التعليمات البرمجية الخاصة بك. هل يمكنك إظهار الكود الذي تستخدمه انتاج النتائج

كما اقترح مايلز، قد يكون ATOF () أبسط. يمكنك تحويل كائن سلسلة إلى سلسلة AC عن طريق الاتصال بوظيفة العضو C_STR ():

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

إليك بعض المعلومات الأخرى: 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;
}

يعطيني الرمز أعلاه الإخراج التالي:
-2.36907E-39.
0.1

هل أنت فرصة التحقق من قيمة الدوران قبل العودة؟


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;
}

انتاج:
templat = 0.1.
latidible = 0.1.
templat = 0.4.
latdible = 0.4.

يمكنك تشغيل التعليمات البرمجية مع هذه التعديلات (لم تكن تستخدم المعلمة Int في المحطة الطرفية، لذلك أزلت ذلك فقط). أنا أيضا ركض الرمز الخاص بك باستخدام Valgrind دون أخطاء (تسرب الذاكرة فقط).

يبدو أنك لم تحصل على إجابة لقضية الانتخابات الخاصة بك. اقترح آخرون استخدام ATOF (). إذا كنت ترغب في حل المشكلة فيفتك، فابحث في التعليمات البرمجية أدناه. بدلا من وجود متجه لطريقة تنفجر، ضع المتجهات لتجنب الرمز الزائد. لقد غيرت الرمز في Strtodouble كذلك.

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;
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top