如何将包含双精度的std::string转换为双精度的vector ?
How do I convert a std::string containing doubles to a vector of doubles?
我有两种输入,我想使用相同的方法。第一种情况是,给定的形参是一个包含三位数的std::字符串,我需要将其转换为int:
std::string pointLine = "1 1 1";
第二种情况是,给定的形参是一个std::string,其中包含三个"非双精度",我需要将它们转换为双精度:
std::string pointLine = "1.23 23.456 3.4567"
我写了以下方法:
std::vector<double> getVertexIndices(std::string pointLine) {
vector<int> vertVec;
vertVec.push_back((int) pointLine.at(0));
vertVec.push_back((int) pointLine.at(2));
vertVec.push_back((int) pointLine.at(4));
return vertVec;
}
对于第一种情况可以正常工作,但对于应该转换为double类型的行则不行。
所以我在C中尝试了解决方案Double split。我得到分隔符是" "。
这是我现在想到的,但是程序在第一次调用以下方法后崩溃了:
std::vector<double> getVertexIndices(std::string pointLine) {
vector<double> vertVec;
char * result = std::strtok(const_cast<char*>(pointLine.c_str()), " ");
while(result != NULL ) {
double vert = atof (result);
vertVec.push_back(vert);
char * result = std::strtok(NULL, " ");
}
return vertVec;
}
不需要复制,你可以直接从迭代器中初始化vector。
// include <string>, <vector>, <iterator> and <sstream> headers
std::vector<double> getVertexIndices(std::string const& pointLine)
{
std::istringstream iss(pointLine);
return std::vector<double>{
std::istream_iterator<double>(iss),
std::istream_iterator<double>()
};
}
这与整型数的工作方式完全相同。对于"123 456 789"
使用std::istringstream
:
std::vector<double> getVertexIndices(std::string pointLine)
{
vector<double> vertVec;
std::istringstream s(pointLine);
double d;
while (s >> d) {
vertVec.push_back(d);
}
return vertVec;
}
真的很简单。构造一个将从字符串中读取的流。然后使用正常的流提取来填充向量。
当然,您可以利用标准库的迭代器适配器和类似的东西来生成如下内容:std::vector<double> getVertexIndices(std::string pointLine)
{
std::vector<double> vec;
std::istringstream s(pointLine);
std::copy(
std::istream_iterator<double>(s) // start
, std::istream_iterator<double>() // end
, std::back_inserter(vec) // destination
);
return vec;
}
作为旁注(感谢@ikh),您可能希望将函数更改为接受const std::string &
-没有必要按值接受字符串
您的尝试的主要问题是strtok()
将修改作为输入传递的指针。对通过std::string::c_str()
获得的指针执行此操作将在字符串对象内部造成严重破坏。
这里提供的所有其他答案都很好。从你所说的,你只需要读取3双精度(x,y,z顶点),所以你可以优化函数使用一些其他固定大小的容器,不分配内存(std::vector
将分配)。在下面的示例中,我使用std::tuple
来返回结果。我还使用了std::stod()
,这是一个c++ 11函数,从字符串中解析双精度。如果转换失败,它将抛出一个异常,这可能对您的应用程序也很有用。
#include <iostream> // std::cout
#include <string> // std::stod
#include <tuple> // std::tuple
std::tuple<double, double, double> getVertexIndices(const std::string & pointLine)
{
size_t xEnd, yEnd;
const double x = std::stod(pointLine, &xEnd);
const double y = std::stod(pointLine.substr(xEnd), &yEnd);
const double z = std::stod(pointLine.substr(xEnd + yEnd));
return std::make_tuple(x, y, z);
}
// Test case:
int main()
{
const std::string pointLine1 = "1 2 3";
const std::string pointLine2 = "1.23 23.456 3.4567";
std::tuple<double, double, double> v1 = getVertexIndices(pointLine1);
std::cout << "x = " << std::get<0>(v1) << std::endl;
std::cout << "y = " << std::get<1>(v1) << std::endl;
std::cout << "z = " << std::get<2>(v1) << std::endl;
std::tuple<double, double, double> v2 = getVertexIndices(pointLine2);
std::cout << "x = " << std::get<0>(v2) << std::endl;
std::cout << "y = " << std::get<1>(v2) << std::endl;
std::cout << "z = " << std::get<2>(v2) << std::endl;
return (0);
}
相关文章:
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- 在 c++ 中从双精度转换为字符串
- 使用 sprintf 和 %g 将双精度转换为字符串的意外结果
- 从双精度转换为整数的显式类型是否始终检查整数溢出?
- C++,遇到将双精度转换为整数的问题
- 在C++中将双精度转换为intptr_t
- 将大双精度转换为科学记数法以用作字符串?
- 了解双精度转换与整数转换中的整数与截断关系
- 将 OLE 自动化日期 (OADate) 双精度转换为结构 tm,而不使用 VariantTime到SystemTime
- 无法在赋值中将"双精度 (*)[4]"转换为"双精度**"
- 将大双精度转换为无符号 int 期间堆栈损坏
- 将双精度转换为本地8位
- 警告从"双精度"转换为"int"
- 如何将双精度转换为浮点指针
- 将双精度转换为整数时出错
- 使用并集将双精度转换为十六进制再转换为双精度
- 是否有可以将每个双精度转换为唯一uint64_t,保持精度和顺序的功能?(为什么我找不到?
- 使用定点表示法将双精度转换为字符串,没有尾随零和机智的冲刺
- 在C++中将双精度转换为字符*/字符串
- 无法将双精度 [] [] 转换为双精度 **