从矢量<string>转换为<double>不带 std::stod 的矢量

Converting from vector<string> to vector<double> without std::stod

本文关键字:lt gt std stod 不带 double string 转换      更新时间:2023-10-16

它始于将vector<string>转换为vector<double>。我在没有 C++11 的情况下使用 gcc,所以我无法使用这种方法。在查看了transpose的算法模板后,我尝试改用该模板,但是模板内部使用的std::stod存在错误(对于 gcc 4.x,导致"stod"不是"std"的成员(
那么为什么不自己编写它,我将 while-loop 与字符串流一起使用(昂贵?

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

不幸的是,我得到:双重释放或损坏(出(:0x00007f4788000ba0***

我认为

这里的问题是

++svec.begin();

不像你想象的那样工作。这不会向前推进向量的开头。相反,它会将一个(临时(迭代器获取到向量的开头,然后递增它。结果,您将陷入无限循环。若要解决此问题,请使用更传统的"容器循环"循环,方法是使用基于范围的 for 循环或仅计算索引。

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

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

  • std::stod是一个C++11函数,所以如果你不使用C++11,那么如果找不到它,它就不是"bug"。
  • 你的意思是std::transform而不是transpose,不是吗?
  • 您很可能会在没有 C++11 和没有 std::stod 的情况下使用std::transform。不幸的是,您没有显示您尝试使用的代码。

那么为什么不自己写呢,我用while循环和字符串流

是的,为什么不呢?

(贵?

:)测量它

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

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

循环条件没有意义。 begin()end()不会改变。这一行有效地读作"只要向量不变空,就做这些事情"。

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

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

它实际上就像"循环遍历字符串向量,在每个元素上使用字符串流来获取双精度值,并将该值添加到结果向量中">一样简单,在 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);
}

如果您没有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是否成功。