我有两种输入,我想使用相同的方法。 第一种情况是给定参数是一个std :: string,包含三个数字,我需要转换为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 split in C。 我知道我的分隔符是&#34; &#34 ;.
这就是我现在提出的,但是在首次调用以下方法后程序崩溃了:
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;
}
答案 0 :(得分:11)
您可以直接从迭代器初始化矢量,而不是复制。
// 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>()
};
}
这与您的整数完全相同。你的int方法不会像"123 456 789"
答案 1 :(得分:8)
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 &
- 不需要按值获取字符串。
答案 2 :(得分:2)
您尝试的主要问题是strtok()
将修改作为输入传递的指针。使用通过std::string::c_str()
获得的指针执行此操作将会对字符串对象造成严重破坏。
这里提供的所有其他答案都非常好。根据您的说法,您只需要读取3个双精度数(x,y,z顶点),这样您就可以优化函数以使用其他不分配内存的固定大小容器(std::vector
将分配)。在以下示例中,我使用了std::tuple
来返回结果。我还使用了std::stod()
这是一个C ++ 11函数,用于解析字符串中的double。如果转换失败,它将抛出异常,这对您的应用程序也很有用。
#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);
}