我有一个带有GCode命令的文本文件。当我遇到一个特定的命令时,我想用新命令在它后面添加一个新行。那部分不是问题。我遇到的问题是该命令具有以下形式G0/G1 Xnnn Ynnn Znnn
,其中X / Y / Z参数可能存在或不存在(至少需要一个,但不是全部)。我想要的是X / Y / Z之后的数字。我目前的工作解决方案是使用substring(start + 1, end - 1)
和find(X/Y/Z)
,然后检查所有组合:
size_t xPos = str.find("X");
size_t yPos = str.find("Y");
size_t zPos = str.find("Z");
float x, y, z;
if(xPos != std::string::npos && yPos != std::string::npos)
x = std:stof(str.substring(xPos + 1, yPos - 1);
这是一种合适的方法吗?我是不是太复杂了?
编辑:因此,输入看起来像G0 X101.1 Y102.3
或G0 Y122
或G0 X55 Z123
,因此n
指的是一个数字,命令就是告诉我3D打印机在给定方向上移动多少单位,因此可能需要在一个,两个或三个方向上移动。
答案 0 :(得分:2)
每次我需要用C ++解析一些东西时,我都会考虑使用Boost.Spirit。它适用于琐碎和非常复杂的解析任务。
使用Boost.Spirit,它会look like this:
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
#include <vector>
int main()
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
std::string input = "G0/G1 X001 Y123 Z321";
int x, y, z;
bool result = qi::phrase_parse(input.begin(), input.end(),
qi::lit("G0/G1") >> "X" >> qi::int_ >> "Y" >> qi::int_ >> "Z" >> qi::int_ , ascii::space, x, y, z);
if (result)
{
std::cout << "X:" << x << std::endl;
std::cout << "Y:" << y << std::endl;
std::cout << "Z:" << z << std::endl;
}
}
请注意,坐标会直接解析为int
s!
更新:根据您更新的问题多了complicated parsing:
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <boost/optional.hpp>
#include <boost/optional/optional_io.hpp>
int main()
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
std::string input = "G0 X001 Z321";
boost::optional<float> x, y, z;
int cmd;
using namespace qi;
bool result = phrase_parse(input.begin(), input.end(), qi::lexeme[lit("G") >> int_] >> -(lit("X") >> float_) >> -(lit("Y") >> float_) >> -(lit("Z") >> float_) , ascii::space, cmd, x, y, z);
if (result)
{
std::cout << "Command number:" << cmd << std::endl;
std::cout << "X:" << x << std::endl;
std::cout << "Y:" << y << std::endl;
std::cout << "Z:" << z << std::endl;
}
}
答案 1 :(得分:1)
使用std::stringstream
int x, y, z = -1;
std::stringstream ss("G0/G1 X123 Y456");
std::string str;
while (ss>>str) {
if (str.at(0) == 'X') {
std::stringstream(str.substr(1)) >> x;
} else if (str.at(0) == 'Y') {
std::stringstream(str.substr(1)) >> y;
} else if (str.at(0) == 'Z') {
std::stringstream(str.substr(1)) >> z;
}
}