The function of a simple row editing program is to receive the program or data input by the user from the terminal and store the data in the user's data zone. As there is no guarantee that no error will occur when a user inputs data on the terminal, it is obviously not appropriate to "store each character in the user data zone" in the editing program. A good practice is to set up an input buffer to receive a line of characters entered by the user and store them in the user data zone row by row. You can enter a business error and correct the error in time. For example, if you find that the character you just typed is incorrect, you can add a backslash (#) to indicate that the previous character is invalid; if you find that there are many or difficult to remedy errors in the currently typed row, you can enter a backslash (@) to indicate that all characters in the current row are invalid. For example, if the terminal receives the following two lines of characters: whil # ilr # e (s # * s) outcha @ putchar (* s =#++ ); the following two rows are actually valid: while (* s) putchar (* s ++); therefore, this input buffer can be set to a stack structure, each time a character is received from the terminal, the following distinction is made: if it is not a return character or a return character, it is pushed to the top of the stack; if it is a return character, delete a character from the top of the stack. If it is a regularizedcharacter, the character stack is empty. The preceding process can be described using the following algorithm:
Figure: the row editing program algorithm is used to input several rows of programs or data in the format. Each row cannot exceed 200 characters. Output after processing by the line editing program. Sample input whil # ilr # e (s # * s) outcha @ putchar (* s = # ++); sample output while (* s) putchar (* s ++ );
# Include <string. h> # include <ctype. h> # include <malloc. h>/* malloc () and so on */# include <limits. h>/* INT_MAX, etc. */# include <stdio. h>/* EOF (= ^ Z or F6), NULL */# include <stdlib. h>/* atoi () */# include <math. h>/* floor (), ceil (), abs () * // * function Result Status Code */# define TRUE 1 # define FALSE 0 # define OK 1 # define ERROR 0 # define INFEASIBLE-1 typedef int Status; /* Status indicates the function type, and its value is the function result Status code, such as OK */typedef int Boolean;/* Boolean indicates a Boolean value. TRUE or FALSE */# define STACK_INIT_SIZE 10/* Initial bucket allocation */# define STACKINCREMENT 2/* bucket allocation increment */typedef char SElemType; /* define the stack element type as integer */typedef struct SqStack {SElemType * base;/* The base value is NULL */SElemType * top before and after stack construction; /* stack top pointer */int stacksize;/* currently allocated storage space, in the unit of elements */} SqStack; /* sequential stack */Status InitStack (SqStack * S) {/* construct an empty stack S */(* S ). base = (SElemType *) malloc (STACK_INIT_SIZE * sizeof (SElemType )); If (! (* S ). base) exit (OVERFLOW);/* storage allocation failed */(* S ). top = (* S ). base; (* S ). stacksize = STACK_INIT_SIZE; return OK;} Status Push (SqStack * S, SElemType e) {/* insert element e as the new stack top element */if (* S ). top-(* S ). base> = (* S ). stacksize)/* Full stack, append storage space */{(* S ). base = (SElemType *) realloc (* S ). base, (* S ). stacksize + STACKINCREMENT) * sizeof (SElemType); if (! (* S ). base) exit (OVERFLOW);/* storage allocation failed */(* S ). top = (* S ). base + (* S ). stacksize; (* S ). stacksize + = STACKINCREMENT;} * (* S ). top) ++ = e; return OK;} Status Pop (SqStack * S, SElemType * e) {/* If the stack is not empty, the top element of S is deleted, return the value with e and OK; otherwise, ERROR */if (* S) is returned ). top = (* S ). base) return ERROR; * e = * -- (* S ). top; return OK;} Status ClearStack (SqStack * S) {/* Set S to empty stack */(* S ). top = (* S ). base; return OK;} Status DestroyStack (SqStack * S) {/* destroy stack S, S not And then */free (* S ). base); (* S ). base = NULL; (* S ). top = NULL; (* S ). stacksize = 0; return OK;} Status StackTraverse (SqStack S, Status (* visit) (SElemType )) {/* call the visit () function for each element in the stack from the bottom of the stack to the top of the stack (). * // * Once visit () fails, the operation fails */while (S. top> S. base) visit (* S. base ++); printf ("\ n"); return OK;} void LineEdit () // algorithm 3.2 {// use character stack S, receives a row from the terminal and sends it to the data zone of the call process. Char ch, * temp; SqStack S; InitStack (& S); // construct an empty stack S ch = getchar (); // receives the first character while (ch! = EOF) // EOF is the full text Terminator {while (ch! = EOF & ch! = '\ N') {switch (ch) {case' # ': Pop (& S, & ch); break; // stack rollback case '@': ClearStack (& S); break; // reset S to empty stack default: Push (& S, ch ); break; // valid characters are added to the stack, without considering full stack conditions} ch = getchar (); // receives the next character from the terminal} temp = S. base; while (temp! = S. top) {printf ("% c", * temp); ++ temp;} // transfers the characters from the bottom of the stack to the top of the stack to the data zone of the call process; clearStack (& S); // reset S to empty stack printf ("\ n"); if (ch! = EOF) {ch = getchar (); // read the first character} DestroyStack (& S) ;}int main () {LineEdit (); return 0 ;}