在一个小玩具项目中实现终端历史记录功能

问题描述 投票:0回答:1

我正在尝试模拟终端模拟器的一个特定功能,即解析先前命令的能力。

我真正天真的方法是尝试创建一个循环缓冲区,并使用下一个和上一个命令浏览它,它本质上将视图更改为历史缓冲区中的当前行。

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';
}

根本不可行,我的代码已经变得混乱,我正要重写,有哪些方法可以实现这个功能?循环缓冲区是执行此操作的正确方法吗?我不确定如何对上下遍历缓冲区的函数施加约束。我更喜欢寻找所需功能的想法和简单资源/实现。

c data-structures
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);
    
© www.soinside.com 2019 - 2024. All rights reserved.