我正在try 模拟终端仿真器的一个特定功能,即解析前面的命令的能力.

我真正天真的方法是try 创建一个循环缓冲区,并使用NEXT和PREV命令在其中导航,该命令实质上将视图更改为历史缓冲区中的当前行.

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

根本不可行,我的代码变得杂乱无章,我即将重写,有什么方法可以实现这个功能?周期性缓冲是实现这一目标的正确方式吗?我不确定如何对遍历缓冲区的函数施加约束.我更倾向于寻找所需功能的 idea 和简单的资源/实现.

推荐答案

按照要求,下面是如何在代码中实现堆栈解决方案. 我没有发现 struct 构件front, rear, view的用处,但我将它们完好无损地留在了 struct 中.也许我添加的全局变量stack_top替换了其中一个或两个 struct 成员的意图?

我不喜欢全局变量,但堆栈指针(stack_top)需要由两个函数共享,所以我们就在这里.如果全球赛太可怕了,你当然可以用不同的方式进行编码.它当然可以被添加为GT_SCQueue的成员,这是一个简单的修改,对吗?

经过测试、可运行的代码如下:https://godbolt.org/z/bfr4bfr5o

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


#define GT_SCQUEUE_SIZE 1000

/* Only one modification to the structure ... */
typedef struct {
    char *buffer[GT_SCQUEUE_SIZE]; /* ... here. */
    int front;  /* unused */
    int rear;   /* unused */
    int view;   /* unused */
} GT_SCQueue;


GT_SCQueue scq = {{0}, -1, -1, 0};
int stack_top = -1;

/*---------------------------------------------------------------------------------------------
    GT_SCQueue_Push()

    Places the item in param string onto the stack.
*---------------------------------------------------------------------------------------------*/
int GT_SCQueue_Push(GT_SCQueue* scq, const char* string) 
{
    if(stack_top < GT_SCQUEUE_SIZE-1)
    {
        stack_top++;
    }
    else 
    {
        printf("Stack Overflow items: %d  Max: %d .... moving 1st item out of stack.\n", stack_top+1, GT_SCQUEUE_SIZE);
        return 0;
    }
    /*Add new item on the right */
    scq->buffer[stack_top] = strdup(string);

    if(!scq->buffer[stack_top])
    {
        printf("GT_SCQueue_Push() memory error!\n");
        return 0;
    }
    printf("GT_SCQueue_Push() added element [%s].  Elements on the stack: %d  Available: %d\n", 
            string, stack_top+1, GT_SCQUEUE_SIZE-(stack_top+1) );

    /* Return success */
    return 1;
}


/*---------------------------------------------------------------------------------------------
    GT_SCQueue_Pop()

    Pops an item off the stack and into param string.
*---------------------------------------------------------------------------------------------*/
int GT_SCQueue_Pop(GT_SCQueue* scq, char *string) 
{
    if(stack_top < 0)
    {
        printf("UNDO Stack Underflow -- index: %d", stack_top);
        return 0;
    }
    strcpy(string, scq->buffer[stack_top] );
    free(scq->buffer[stack_top]);
    scq->buffer[stack_top] = NULL;
    printf("GT_SCQueue_Pop() popped element index: %d of string [%s]\n", stack_top, string);
    stack_top--;
    return 1;
}

int main() 
{
char b1[20];

    GT_SCQueue_Push(&scq, "Hello You!");
    GT_SCQueue_Pop(&scq, b1);
    printf("Report from main() -- Popped [%s]\n", b1);
}

输出:

    T_SCQueue_Push() added element [Hello You!].  Elements on the stack: 1  Available: 999
    GT_SCQueue_Pop() popped element index: 0 of string [Hello You!]
    Report from main() -- Popped [Hello You!]

C++相关问答推荐

理解C中的指针定义

C中出现分段错误后关闭文件

找出文件是否包含给定的文件签名

MISRA C:2012 11.3违规强制转换(FLOAT*)到(uint32_t*)

GCC引发不明确的诊断消息

为什么net/if.h在ifaddrs.h之前?

在列表中插入Int指针(C)

将数据移动到寄存器时出现分段故障

在C语言中,是否可以使枚举数向后计数?

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

判断X宏的空性

X64:并发写入布尔数组

如何使用C++在控制台中以彩色打印被阻止的客户端

我的C函数起作用了,但我不确定为什么

如何只获取字符串的第一个单词,然后将其与c中的另一个单词进行比较?

递归打印二维数组(C编程)

为什么我在C代码中得到一个不完整的类型?

正在try 理解C++中的`正在释放的指针未被分配‘错误

unions 的原子成员是个好主意吗?

如何使crc32的结果与cksum匹配?