如何为C++ getline()函数添加过滤规则提取G1指令的X、Y坐标
G代码解析:提取G1指令中的X、Y坐标数值
问题描述
我需要解析G代码,提取每行中以G1开头的指令里的X和Y坐标数值。目前使用基础的getline()函数只能读取并输出整行内容,不清楚如何添加过滤规则,只提取符合条件的X、Y数值。
G代码示例:G1 X123.456 Y125.425 Z34.321
当前使用的C++代码如下:
#include <iostream> #include <fstream> #include <vector> #include <sstream> #include <fstream> using std::cout; using std::cerr; using std::endl; using std::string; using std::ifstream; using std::vector; int main() { string filename("test1.gcode"); vector<string> lines; string line; ifstream input_file(filename); if (!input_file.is_open()) { cerr << "Could not open the file - '" << filename << "'" << endl; return EXIT_FAILURE; } while (getline(input_file, line)){ lines.push_back(line); } for (const auto &i : lines) cout << i << endl; input_file.close(); return EXIT_SUCCESS; }
解决方案
getline()本身不支持过滤规则,我们需要在读取每行后对内容进行判断和解析,具体步骤如下:
- 读取每行后,先判断该行是否为
G1指令(需跳过行首可能存在的空白字符) - 若为
G1指令,将行内容传入stringstream拆分元素,提取X、Y后的坐标数值 - 直接处理读取到的数值,无需存储所有行内容(节省内存)
修改后的代码如下:
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <cctype> using std::cout; using std::cerr; using std::endl; using std::string; using std::ifstream; using std::stringstream; // 跳过字符串开头的空白字符 string trimLeadingWhitespace(const string& s) { size_t start = s.find_first_not_of(" \t\n\r"); return (start == string::npos) ? "" : s.substr(start); } int main() { string filename("test1.gcode"); string line; ifstream input_file(filename); if (!input_file.is_open()) { cerr << "Could not open the file - '" << filename << "'" << endl; return EXIT_FAILURE; } while (getline(input_file, line)){ string trimmedLine = trimLeadingWhitespace(line); // 判断是否以G1开头 if (trimmedLine.substr(0, 2) == "G1") { stringstream ss(line); string token; double x = 0.0, y = 0.0; // 拆分每行内容,提取X、Y数值 while (ss >> token) { if (token.size() > 0) { if (token[0] == 'X') { // 提取X后的数值部分 x = stod(token.substr(1)); } else if (token[0] == 'Y') { // 提取Y后的数值部分 y = stod(token.substr(1)); } } } // 输出提取到的X、Y坐标 cout << "G1指令坐标: X=" << x << ", Y=" << y << endl; } } input_file.close(); return EXIT_SUCCESS; }
代码说明
trimLeadingWhitespace函数:跳过行首的空格、制表符等空白字符,避免因行首空白导致无法识别G1开头- 使用
stringstream拆分每行内容:将整行内容按空白分割成多个token,逐个检查是否为X或Y开头的指令 stod函数:将X/Y后的字符串转换为双精度浮点数,获取坐标数值- 边读边处理:无需将所有行存入vector,直接读取一行处理一行,减少内存占用
内容的提问来源于stack exchange,提问作者Mohit
相关产品推荐
相关产品推荐

