 So, let us get cracking. We will do a very brief review of the editor class, where I have added some more member functions. Last time, we had said that just as we had defined a class called stack.h in a separate file. Similarly, we could define another class called editor. For the sake of convenience, we had included the entire editor class definition as a part of your main file itself. So, this is what we had looked at. There is a preliminary documentation. So, we were defining the editor class. Now, notice that we had said yesterday that we might want to examine somewhere in between as to what is being edited. And therefore, we would like a function which in the midst of editing should be able to display to me what is the status of editor. If you recall, the main definition of the editor class used two private data members, which were two stacks, which in turn were defined as part of the stack class, L stack and R stack. And we defined of course an array called text, an array called word for adding an integer number called size and cursor. Notice the member functions which we had defined. We had an init member function, move cursor member function, text insert member function, text delete member function. What I have added is a text display member function. What I have also added is a text return member function. Because if I give something for editing, at the end I must get back the edited version. So, I need a member function which will return whatever is the status of editor, the edited text should be given back to me. So, I have a character array here in which I expect the text to be returned. And I have an out length or the length of the edited text. Notice that when I give the text in, I need to define a parameter, which is just an absolute parameter because the value will be copied from the main parameter. I do not need to return back anything. But in case of returning of the text, edited text, I must reassign the appropriate value of the size of the edited text back to the calling function parameter. And therefore, the calling function must use a pointer, which is what is indicated here. This is of course an array. So, we will look at, we will just go through the other function definitions, which we have already seen. But we will specifically look at the definition of the two new functions, which we have defined here. Text display and text return. Please remember for both of these, we shall be using the L stack and R stack. Just to recall, we have a definition of a cursor. All characters to the left of the cursor are pushed onto L stack. All characters to the right of the cursor are pushed onto the right stack. That will be the status of the editor at any point in time. So, this is of course the initialization. We are all familiar with this. I just push the text into an internal array and then I initialize these two stacks and I push all my characters onto the right stack. So, whatever is the size, from size minus 1 to 0, because I have to push the characters, the last character should be the first one to be pushed in, because that is the order in which the character should appear on the stack. Move cursor is very straightforward. I just check whether the cursor is within bounds. If not, I give error messages. Otherwise, depending upon whatever is the cursor position relative to the new cursor position, where I want to move, I will shift characters either to left stack from right stack or to right stack from left stack. So, it is a very simple implementation. Again, the way how the stacks are handled is hidden from us. It is part of stack dot h. So, as long as I use push and pop commands, I am comfortable that the commands will be executed proper. Text insert member function will insert some text at the cursor position to the left of it. As we said, we will expect a word to be added to be given to us along with its length. We are just temporarily pushing it into an internal array here, word i and then we find out the length of that word. So, notice that this int length, which is given is irrelevant, because we are using our own calculation here. If the total size after addition of the word becomes larger than the capacity, I say sorry. Otherwise, I will just push every character in that word onto the left stack, which is what is text insertion. This is the text display function. You will recall, we had mentioned yesterday that since I know the cursor and since I know all characters to the left of the cursor are in left stack and right of the cursor on the right stack, I could write a display function by which I could pop out all characters from both the stacks and display them. So, it is entirely possible to display characters in this display function itself. However, that would be a destructive operation. Why? Because the stack continues to contain the text to be edited. I have not yet finished editing. I might want display at any point in time just for cross check, in which case it is not proper to destroy the contents of the stacks. And that is why if we want to use this display, then I have written another function as a part of the stack family. So, the stack class, why I need to do that? I could have very well popped characters from left stack and right stack and showed them whenever display function is involved. But then I will have to remember all the text and again push them back. And that could be a lot of work if there are millions of characters. Now, this is happening because I have no access directly to the arrays which contain the characters in L stack and R stack. Please remember the stack.h implementation of the class internally used a member data element which was an array. And in fact, the top of the stack was a pointer to an array element. And we were pushing characters from 0th element onward till the stack was full. So, there is indeed an array available because that is how we have implemented it. Of course, we need not concern ourselves how it is implemented. But we guess that instead of popping out characters and then pushing them back again, it may be better to write a function at the stack class itself to display the stack. Because then whatever be the internal implementation, the stack class member functions will have access to those private data elements. And therefore, without moving characters anywhere, I could just access the array directly and display all the elements that I wanted. So, that is why I am displaying the stacks. So, I display the stack of characters before the cursor by saying it is stack dot display and after the cursor by saying R stack dot display. The issue is how would the stack dot display function work. So, any idea on how this will work? Recall the stack implementation. In the stack implementation, we had an array S. This was the 0th element, first element, second element and so on. How many elements would be there? In a stack at any point in time, the maximum capacity is of course the text size. So, whether it is left stack or right stack, each stack that we create will have a member element of this array which will be called S. So, any stack within the stack implementation, what is the position indicator of where the last character has been pushed on to the stack. You remember, we had declared a variable called int tops. And in fact, we were pushing characters whenever we push character or pop character command was given. The internal implementation in stack was that we increment tops. We actually push the character and then increment tops. And if we want to pop, we reduce the tops value by 1 and then take out excess that array. So, internal representation uses this S array. So, wherever I want to display any character, the best bet would be to display the corresponding character in the array directly. I don't have to do any push or pop. And push or pop can be done at the higher level, but the implementation has to be done at the stack level. So, I can't access this array outside the class stack. I can access this array only within the class stack. That is why the function display which is required at the editor level, the activity has to be pushed down to the stack level for efficiency sake. So, in any stack, the display function will say that I want to display how many characters, starting with 0, 1, 2, et cetera, et cetera up to a point. What is that point? The value of tops. Whatever is the value of tops for that particular stack, there are characters up to that point. So, consequently, I can simply put an iteration which will say for I is equal to 0, I less than tops, I plus plus. And I can simply say, see out. Do you agree that this will give me the set of characters which are in the stack at any point in time? Yes or no? This is the implementation which is completely non-destructive. I am merely examining what is there inside. But this examination cannot be done outside the class stack because all those data elements that we are referring to here are private data elements to class stack. They are not accessible from outside. That is the reason why when we looked at this, we said that editor colon colon text display function will actually invoke either an, not either, both the s-stack display and right-stack display to display both stacks. So, we know exactly what is to the left of the cursor, what is to the right of the cursor, we of course know the cursor position. So, this would be the definition of that stack display function. Very simple. Nothing else is required here. For int I equal to 0, I less than tops, I plus plus, c out, s I. Please note that this is a bare minimal function. So, it does not put any fancy output. It will just output characters one by one, whatever are the characters. There is a new line character. It will go to the new line. If there is a null character, the c out will do what? It will still print backslash 0 because we are printing a character individually. We are not printing a string. It is a significant difference between printing characters and handling characters and handling strings. You delete basically from the left stack. So, always you say left stack dot pop and you will forget those characters which come out. You must always for insertion or deletion, reset the cursor to the correct position and reset the size of the text that is being edited. This is the additional member function that we have written because anytime we give a text to be edited, then that editing will happen through the edit commands which we had briefly described last time and which we just glossed through. Namely insert a word, move cursor, delete so many characters and there is a command called quit. Now, obviously when we quit, we want the edited text to be written to us and that is why this function. So, observe what this function does. Notice that this is star out length. So, it will set star out length to size, whatever is the current size. This size is the totality of characters on the left stack and right stack together. That is the edited text. Now, if cursor is 0, that is fine. But if cursor is not 0, that means there are some characters on this side and some characters on that side. So, I move cursor to 0. Observe that when I move cursor to 0, this is an editor command itself. But this function will pop all characters from the left stack and push them onto the right stack. So, I will have all my text which has been edited on the right hand side stack and once I have that, I will insert every character into the text stack. Of course, if I wanted to be more efficient, I could have done this assignment from both left stack and right stack by popping characters, but my logic would become more complicated. So, this is the case where clearly some loss of efficiency is all right for simplicity of code or for straightforwardness of the code. When I go back in this array, I will have the written text or edited text. The main program itself, I have all these things. The difference now is last time we have seen a sample editing where the editing commands were incorporated in the main program itself. But our idea is to permit editing by any user who gives editing commands on the keyboard. And the editing commands could be insert, move, delete, etc. And the text itself would be available in some file. We therefore define a file, read its file name and after getting the file name, we want to open the file and read the file in its entirety for editing. So, last time we had seen that we of course have error checking whether the file exists or not. But otherwise, the way we read the entire text is, you will recall that we had decided to use direct access and read the whole block. In order to figure out what is the size of the file, we first set f seek and you go to seek end. And when you go to seek end, you get the file position by using the function f tell. f tell on any file pointer will give you where the current position of the file pointer is like knowing cursor in your edit. And because this f seek will set that pointer to the last, you will know that what is written by f tell is the file pos which is the size of the file. So, number of bytes, remember the byte positions like an array start from 0. So, 0, 1, 2, 3, 4 and whatever is the final position that is given will be actually just after the end of file because you are setting it to seek end and that will be the size of the file. Knowing this size, you say so much size. Now, you know what is the editor capacity which is the text size. So, you say if that is greater, I would not be able to handle it and quit at this juncture itself. Otherwise, you rewind the file. Remember, f seek would have pushed the internal file positioning pointer to the end. So, you bring it back all the way to the beginning and then you do a read. The read can be done in one of the two ways. You can ask the file system to read one block of size, just one unit. So, you could have said size comma 1. So, size number of bytes just one unit of that block. Alternatively, you can say read one byte, but read size number of bytes. So, block is one byte here. Remember, I had said that this could be slightly inefficient, but it is inefficient if you include a get see kind of function within an iteration. When you give everything in a single command, it is the operating system which optimizes the entire command and the operating system in fact will read the entire set of bytes in that file in the most efficient manner and get that to you. You will get that in this text. Since there is no guarantee that there is a backslash 0, in fact there is a guarantee that there will be no backslash 0 on the text file in the days, I have insert one to make it like a character string. You can recall that if you re-run, if you examine the stack functions and the editor functions properly, except when you are adding a word where backslash 0 has a significance since you want to treat the word as a string, otherwise you actually don't need backslash 0. You know exactly the count of characters, what is to be pushed, what is to be popped, etc. There is no not necessary. Having read this text, I initialize the my edit. My edit is an object of the class editor type. Now I have to implement the command handling. Since the commands are single character commands it is best handled by a switch statement. So here is the implementation. I set up a infinite iteration. Do something something while at the end. What I am going to do is every time in that iteration I will read one command, execute it and go for reading another command. So that is the process. Of course some commands require parameters. Like insert requires a word, move requires a position, delete requires a number of characters to be deleted. But once I know what that command is, I know exactly what will be the parameter following it and I can read that parameter additionally. So this is what is being done. I read an edit command which is actually a single character. I switch on that single character. So it is like a number of ifs. If edit character is I do this, if edit character is m do this, if edit character is q do this etc. And the cases say if case is m which means move, so I move cursor to the given position. I read pause now because that is a parameter for move. So whatever is the pause value I say my edit not move cursor pause. The implementation of each edit command is extremely simple now because for each of these commands I have actually written member functions in the editor class. So I don't have to write any code here. These are for insertion and deletion of text. If the command given is I, that is insert, then I have to read a word which is to be inserted. So I read add a word, I calculate add a word length and push it, I move it, I rather call my edit not text insert which will insert this word which means internally it will push these characters onto the left stack. Similarly delete, I want to delete characters at the cursor to the left of the cursor. So I read the number of characters to be deleted and I will simply invoke text delete function. Notice that no error checking is required here because that is presumably being done by the implementation of the insert and delete. If I exceed the size or if the stack becomes more than full or if the stack is empty etc. the appropriate messages would be taken care of by that group of functions. Finally the case Q when I want to quit. Whenever I give a Q command I have finished editing extract edited text and quit. So I say my edit dot text return. Observe the slight difference in invoking text return versus invoking init. While we are invoking init we were required to give the text array containing text to be edited and the size. But the size was not reflected back even if it changed in the init function. Of course it did not. In this particular case we don't know the size of the edited text. Only the editor member knows. So I say my edit dot text return out text comma and outlet. So I pass a pointer so that by reference I will get the result back. Then of course I insert a backslash 0 if I want to print the entire thing as a text or whatever text string and I finish this off. There is a default adder because users who are typing command may not always type correctly. Somebody type z for example. There is no edit command for z. So I have to say something whenever a wrong command is given and what I am saying is sorry cannot recognize as the default. Notice the use of break statement after every case so that I will get out of this and when I execute this default of course I fall down. I don't need to use a break statement. This may not be adequate checking. There is an additional possible of error when users give say insert and don't give a word at all or they say delete and don't give a number. They give some abrakat abrakastring. It is therefore normally what is done professionally is you don't at all believe that the user input will be correct. You always capture characters, analyze those characters, use functions like is numeric, is alpha to ensure what that character is and then extract it using just like you have scanf, you have scanf. So you can do a scanf or string scanf. So assemble all the input characters in a string and do an scanf after validating every character to be right. That is the work that you need to do. But if nothing is there that the wrong character is given you just get out. So you see these few lines of code M for move implemented by a single line of code actually I for insert implemented again by one input and text insert D for delete implemented by using text delete, Q for quit implemented by invoking text return and invoking default for anything else. That's how simple the editor functionality becomes. Remember the do statement at the beginning we said there will be infinite loop where I will keep reading characters. So I have this while edit command is not equal to Q. If edit command is Q I get out otherwise I go back and look for other command and that I say is size of edited text is so and so and I output the output text. So this is how the editing would be performed. Here is a sample text. Enter the name of the file. I have entered some sample text in my text.txt text to be edited is hello CS 101 students greetings for the festive season. Do not forget your weekly report. Goodbye. Let us say one of my TA points out that look a number of students will be enjoying Diwali vacation and anyway the final report submission is going next week. So what is the point in asking people to submit a weekly report during a week which has a lot of holidays. So he prepares these editing commands. He says move cursor to 87 and insert enjoy. This will by the way come just before goodbye. Then he says move cursor to 61 and delete seven characters. So this is the final message. There was there was no TA when I was constructing an example. I realized that next week because of the number of emails that I have got saying I am going away. I am going away. Etc. Etc. The batches may not be functioning at full strength for their project during the next week. I realize that. However there is one caveat to this. This is by the way the true announcement. So you don't have to submit a weekly report next week. However the individual members of the batch must remain accountable to the progress of the project because the next week is your final submission and therefore set up an email contact or whatever it is spent at least one or two hours during the festive days but do contribute so that your project turns out to be best. Don't forget that the project evaluation has a very large share of percentage of the evaluation. Thank you.