本程式模擬 DOS 時代行編輯器核心邏輯:利用兩個動態棧(S 為當前行緩衝,D 為輸出暫存)實現字符級編輯,支援退格鍵(#)刪除單字符、行刪除鍵(@)清空當前行、EOF 結束輸入。展示了棧結構在文本處理中的經典應用。
SqStack#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
struct SqStack {
char *base; // 棧底指針
char *top; // 棧頂指針(指向下一可用位置)
int stacksize; // 當前分配容量
};
InitStack分配初始空間,top=base 表示空棧。
push(自動擴容)void push(SqStack &S, char e) {
if (S.top - S.base >= S.stacksize) {
S.base = (char*)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(char));
if (!S.base) exit(1);
S.top = S.base + S.stacksize; // 修正 top 指針
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
}
popchar pop(SqStack &S, char &e) {
if (S.top == S.base) return 0; // 空棧失敗
e = *--S.top;
return e;
}
注意:原代碼回傳型別為 char 但邏輯上應為 bool/int 指示成功;此處修正為回傳字符並以引用參數帶出值。
ClearStack:top = base,O(1)。DestroyStack:free(base) 釋放記憶體。StackEmpty:top == base。while ((ch = getchar()) != EOF) {
// 處理單行:讀至 '\n' 或 EOF
while (ch != EOF && ch != '\n') {
switch (ch) {
case '#': pop(S, e); break; // 退格:刪除最後一字符
case '@': ClearStack(S); break; // 行刪除:清空當前行
default: push(S, ch); break; // 普通字符入棧
}
ch = getchar();
}
// 行結束:將 S 逆序轉入 D,再從 D 彈出輸出,實現正序列印
while (!StackEmpty(S)) { pop(S, e); push(D, e); }
while (!StackEmpty(D)) { pop(D, e); putchar(e); }
ClearStack(S);
}
S 自然保存輸入順序(棧底→棧頂 = 首字符→尾字符)。為正序輸出,先整體倒入 D(反轉),再從 D 彈出列印。realloc 保證任意長度行均可處理,無固定緩衝區溢出風險。# 模擬 Backspace,@ 模擬 Ctrl+U (Unix) / Esc (DOS) 行殺除。stdbool.h 替代自定義 true/false。SIGINT)優雅退出。getchar() 為 _getch() 並處理 \r\n。以不足 100 行代碼完整演示:動態記憶體管理、棧 ADT 設計、字符流處理、控制字符解析、雙緩衝反轉技巧。是「資料結構」課程從理論走向工程實踐的優秀微型專案。