我目前正试图为基于AVR的步进电机控制器构建一个字符串解析器.这个 idea 是观察一个输入字符串在MIDI上,然后将这个字符串分解成几个子缓冲区,最终将找到他们的方式进入一组运动控制行为.考虑以下分隔符:
'<' - START
'%' - CHANGE BUFFER
'>' - STOP
'A' - Clockwise
'B' - Counterclockwise
我会取一个有点任意宽的字符串,看起来像1234A%7743B,然后把它变成"马达1顺时针方向1234步,马达B逆时针方向7743步".<>
到目前为止,我已经提出了以下解决方案
#include <stdio.h>
#include <stdint.h>
#define TARGET 12
typedef struct
{
uint8_t STRING_SEL;
char X [32]; // buffer X
char Y [32]; // buffer Y
uint8_t iX; // buffer X iterator
uint8_t iY; // buffer Y iterator
uint8_t PTR_CTR;
char* Xptr; // pointer to buffer X
char* Yptr; // pointer to buffer Y
uint8_t * iXptr; // pointer to buffer X iterator
uint8_t * iYptr; // pointer to buffer Y iterator
char ** PTR_ARR [2]; //pointer to array of buffer initial value pointers
uint8_t ** CTR_ARR[2]; //pointer to array of buffer iterator pointers
} parser_manager;
static parser_manager mgr = {
.STRING_SEL = 0,
.X = {[0 ... 31] = 0},
.Y = {[0 ... 31] = 0},
.iX = 0,
.iY = 0,
.PTR_CTR = 0,
.Xptr = &mgr.X[0],
.Yptr = &mgr.Y[0],
.iXptr = &mgr.iX,
.iYptr = &mgr.iY,
.PTR_ARR = {&mgr.Xptr, &mgr.Yptr},
.CTR_ARR = {&mgr.iXptr, &mgr.iYptr}
};
这让我陷入了三星级的编程地狱,并为讨厌的成员访问提供了自己,比如:
char EXPECT_CHAR = *(*(*(mgr.PTR_ARR + mgr.PTR_CTR)) + (***(mgr.CTR_ARR + mgr.PTR_CTR)));
(mgr.Y[TARGET] == EXPECT_CHAR) ? printf("1\n") : printf("0\n");
为什么要做这么丑的事?我的基本原理是,在解析传入的字符时,我会 for each '%'字符递增PTR_CTR,从而干净地切换迭代器和缓冲区.然后,我可以通过添加缓冲区和指针到 struct 体,然后扩大PTR和CTR数组,将其扩展到N个电机.
我可以看到,我可以用计数器数组为自己节省一个间接级别,因为它不需要是双指针array.
这感觉像是解决这个问题的一种非常不雅观的方式.我如何让这个过程变得更干净?到目前为止,我唯一的 idea 是转向固定宽度的包装,消除了这种虚假的活力的必要性.