我正在尝试模拟终端模拟器的一个特定功能,即解析先前命令的能力。
我真正天真的方法是尝试创建一个循环缓冲区,并使用下一个和上一个命令浏览它,它本质上将视图更改为历史缓冲区中的当前行。
typedef struct {
char buffer[GT_SCQUEUE_SIZE][GT_SCQUEUE_STRING_SIZE];
int front;
int rear;
int view;
} GT_SCQueue;
GT_SCQueue scq = {{{0}}, -1, -1, 0};
void GT_SCQueue_Push(GT_SCQueue* scq, const char* string) {
if (++scq->rear == GT_SCQUEUE_SIZE) {
scq->rear = 0;
}
if (scq->front == scq->rear) {
scq->front = (scq->rear + 1) % GT_SCQUEUE_SIZE;
}
if (scq->front == -1) {
scq->front = 0;
}
strncpy(scq->buffer[scq->rear], string, GT_SCQUEUE_STRING_SIZE - 1);
scq->buffer[scq->rear][GT_SCQUEUE_STRING_SIZE - 1] = '\0';
}
根本不可行,我的代码已经变得混乱,我正要重写,有哪些方法可以实现这个功能?循环缓冲区是执行此操作的正确方法吗?我不确定如何对上下遍历缓冲区的函数施加约束。我更喜欢寻找所需功能的想法和简单资源/实现。
我认为以下改编将最适合您的代码。
我想到的优点:
1.) GT_SCQUEUE_SIZE 现在会变得非常大,因为
GT_SCQueue.buffer
将只是一个指针数组,而不是像以前那样的字符串长度内存卷。
2.) strdup() 在执行过程中分配内存——而不是提前分配。有点像推荐的链表解决方案(当然不是实际上)。
3.) 这种修改对我来说似乎没有多大的破坏性。请参阅代码中的注释以了解更多详细信息:
/* Only one modification the structure ... */
typedef struct {
char *buffer[GT_SCQUEUE_SIZE]; /* ... here. */
int front;
int rear;
int view;
} GT_SCQueue;
/* Simply replace the strncpy() line in your code with this one.
* strdup() allocates memory and makes a copy of the string. We assign that memory
to the appropriate index of the structure here: */
scq->buffer[scq->rear] = strdup(string);