在没有std :: stod的情况下从vector <string>转换为vector <double>

时间:2016-02-15 21:04:04

标签: c++ gcc vector

首先将vector<string>转换为vector<double>。我使用没有C ++ 11的gcc,所以我无法使用this方法。在查看transpose的算法template之后,我尝试使用模板,但模板内部使用了std::stod int i = 0; while (svec.begin() != svec.end()) { stringstream(*svec.begin())>> dvec[i] ;//svec: strings, dvec: doubles //dvec[i] = std::stod(*svec.begin()); ++svec.begin(); i++; } (对于gcc 4。导致'stod'的x不是'std'的成员)
那么为什么不自己编写它并使用while循环与stringstream(昂贵?):

ModuleActionCollection Actions = new ModuleActionCollection();
Actions.Add(GetNextActionID(), 
            Localization.GetString("EditModule", this.LocalResourceFile),
            "", "", "", EditUrl(), false, 
            SecurityAccessLevel.Edit, true, false);
return Actions;

不幸的是我得到:双免费或腐败(外出):0x00007f4788000ba0 ***

3 个答案:

答案 0 :(得分:4)

我认为这里的问题是

++svec.begin();

并不像你想象的那样工作。这并没有向前推进向量的开始。相反,它得到一个(临时)迭代器到向量的开头,然后递增。结果,你将陷入无限循环。要解决此问题,请在容器上使用更传统的循环&#34;通过使用基于范围的for循环或仅计算索引来循环。

我也注意到你是通过索引写入dvec的。在没有看到初始化dvec的代码的情况下,我无法确定这是否安全,因为如果你还没有调整向量的大小,这将会结束并导致未定义的行为。即使你确实正确设置了它,因为循环断了,我的猜测是这最终会写出向量的结尾并直接触发问题。

答案 1 :(得分:3)

首先,让我们澄清一些困惑:

  • std::stod 一个C ++ 11函数,所以如果你不使用C ++ 11,那么它就不是&#34; bug&#34;如果找不到。
  • 您的意思是std::transform而非transpose,不是吗?
  • 如果没有C ++ 11且没有std::transform,您可以很好地使用std::stod。很遗憾,您不会显示您尝试过的代码。
  

那么为什么不自己编写它并使用while-loop with stringstream

是的,为什么不呢?

  

(昂贵的):

测量它:)

但是你不太可能注意到差异。

    int i = 0;
    while (svec.begin() != svec.end()) {

循环条件没有意义。 begin()end()不会改变。这条线有效地读作&#34;只要矢量不变空即可做到这一点&#34;

    stringstream(*svec.begin())>> dvec[i] ;//svec: strings, dvec: doubles
    //dvec[i] = std::stod(*svec.begin());
    ++svec.begin(); i++;
    }

我说你正在思考这个问题。您获得的崩溃可能来自这样一个事实:当dvec[i]仍然为空时您访问dvec,并且您实际上从未向其中添加元素。这是未定义的行为。

它就像&#34;循环通过字符串向量一样简单,在每个元素上使用字符串流来获取double值,并将该值添加到结果向量&#34; ,用C ++ 03表示为:

// loop through string vector
for (std::vector<std::string>::const_iterator iter = svec.begin(); iter != svec.end(); ++iter)
{
    std::string const& element = *iter;

    // use a stringstream to get a double value:
    std::istringstream is(element);
    double result;
    is >> result;

    // add the double value to the result vector:
    dvec.push_back(result);
}

答案 2 :(得分:0)

如果您没有stod(已在C ++ 11中添加),则可以使用strtod并将其应用于与您拥有的C ++字符串对应的C字符串。从您链接的方法复制并进行更改(并清理格式):

std::vector<double> convertStringVectortoDoubleVector(
    const std::vector<std::string>& stringVector){
        std::vector<double> doubleVector(stringVector.size());
        std::transform(stringVector.begin(), stringVector.end(), 
            doubleVector.begin(), [](const std::string& val)
                {
                    return strtod(val.c_str(), 0);
                });
        return doubleVector;
}

请注意,如果代码尚未确保每个字符串都包含浮点值的有效表示,则必须添加代码以检查strtod是否成功。