### 思路
1. **初始化栈**:创建一个空栈用于存储有效字符。
2. **读取输入**:读取输入的行数 `n`,然后逐行读取字符。
3. **处理字符**:
- 如果是 `#`,则弹出栈顶字符(如果栈不为空)。
- 如果是 `@`,则清空栈。
- 其他字符则入栈。
4. **输出有效字符**:遍历栈并输出有效字符。
5. **重置栈**:处理完一行后,清空栈以处理下一行。
### 伪代码
```
function InitStack(S):
allocate memory for S.base of size STACK_INIT_SIZE
S.top = S.base
S.stacksize = STACK_INIT_SIZE
return OK
function StackEmpty(S):
return S.top == S.base
function ClearStack(S):
S.top = S.base
return OK
function DestroyStack(S):
free memory of S.base
S.base = NULL
S.top = NULL
S.stacksize = 0
return OK
function Push(S, e):
if S.top - S.base >= S.stacksize:
reallocate memory for S.base with size S.stacksize + STACKINCREMENT
S.top = S.base + S.stacksize
S.stacksize += STACKINCREMENT
S.top = e
S.top += 1
return OK
function Pop(S, e):
if S.top == S.base:
return ERROR
S.top -= 1
e = S.top
return OK
function StackTraverse(S, visit):
while S.top > S.base:
visit(*S.base++)
print newline
return OK
function visit(c):
print c
return OK
function LineEdit():
initialize stack s
read integer n
for i from 1 to n:
read character ch
while ch is not newline:
if ch is '#':
Pop(s, c)
else if ch is '@':
ClearStack(s)
else:
Push(s, ch)
read next character ch
StackTraverse(s, visit)
ClearStack(s)
DestroyStack(s)
function main():
LineEdit()
```
### C++代码
#include <iostream>
#include <cstdlib>
using namespace std;typedef char SElemType;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 2struct SqStack {SElemType *base;SElemType *top;int stacksize;
};Status InitStack(SqStack &S) {S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));if (!S.base) exit(ERROR);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;
}Status StackEmpty(SqStack S) {return S.top == S.base ? TRUE : FALSE;
}Status ClearStack(SqStack &S) {S.top = S.base;return OK;
}Status DestroyStack(SqStack &S) {free(S.base);S.base = NULL;S.top = NULL;S.stacksize = 0;return OK;
}Status Push(SqStack &S, SElemType e) {if (S.top - S.base >= S.stacksize) {S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));if (!S.base) exit(ERROR);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return OK;
}Status Pop(SqStack &S, SElemType &e) {if (S.top == S.base) return ERROR;e = *--S.top;return OK;
}Status StackTraverse(SqStack S, Status(*visit)(SElemType)) {while (S.top > S.base) {visit(*S.base++);}printf("\n");return OK;
}Status visit(SElemType c) {printf("%c", c);return OK;
}void LineEdit() {SqStack s;char ch, c;int n, i;InitStack(s);cin >> n;ch = getchar(); // consume newline after integer inputfor (i = 1; i <= n; i++) {ch = getchar();while (ch != '\n') {switch (ch) {case '#':Pop(s, c);break;case '@':ClearStack(s);break;default:Push(s, ch);break;}ch = getchar();}StackTraverse(s, visit);ClearStack(s);}DestroyStack(s);
}int main() {LineEdit();return 0;
}