 with this, we now go to look at the program once again. So, program to create a file holding data for students. Notice that yesterday's slides also contain this program. These slides are slightly different. What I have done incidentally is that my colleague, Nagesh Karmali by the way wrote this program last night. So, we actually executed it with the same test data. And although there is no new assignment today in the lab docket for today's lab, these programs have been included. One program to create a database file, another program to update the database file, and the actual data file that you have seen. We also included the database file which was created at our end. Remember that although the file can be in some internal format, typically we should be able to visualize it using O D minus X C or something because the values which are getting stored in the record are in fact alphanumeric values. Anyway, so let us go ahead and very briefly again revisit this particular program. This program to create a file holding data for students, struct student info. Notice now we are using the structure. So, again we notice this actually this does not declare any variable or area or anything. It declares that there is a structure type called student info. And any variable of this type will have those many elements care name, care role, int, hostel, float marks, care grade. Again this is well understood from our previous discussion. So, let us go over. The first part of the program is not the main function, but a function to print information about a student. So, here again a small comment helps function to print information about a student given his or her serial number and or along with the structure variable holding the corresponding data. So, this function expects a serial number and a structure to be given as parameters. It will not return any value, but it will simply print the information about that student. Notice that since this function is not required to return any value, it is not declared as int or float or something, it is declared as void. As I had explained to you a void function means that the function has no responsibility of returning a value. Notice that fundamentally a function returns a single value anyway, which is what is described by this particular state. Void print student, struct student info s int s n o. So, just like we write another parameter int s n o float x or whatever, when we write s we have to precede it by the new type definition that we are given. Struct student info. We define an integer i which is an index variable. Now, I say I print the serial number. Notice that this is the information int s n o and the student info structure s or student info type structure s. So, this s structure and serial number is expected to be obtained from the calling program, because as I said this is actually a function to print value. So, somebody gives me the data about one student and his serial number. I print that serial number and that data. So, what do I do here? I print the serial number. I print the name, roll number and hostel. Then, since there are five marks for i equal to 0 to i less than 5, I print s dot marks i. This will print the marks in first test, marks in second test, marks in third test, marks in fourth test, etcetera. Obviously, if I invoke this function initially where I have only roll number, name, hostel, known marks will be 0. This function further prints the grade. So, print percent s backslash and s dot grade. Notice that I have shown here in a commented form an alternate way of printing a string array. If I just give the name of the string array like grade here, all elements of that array are printed without concluding backslash 0. But if I want to print individual characters s dot grade 0, s dot grade 1, there will be two characters a, a, a, b, b, b, c, etcetera, etcetera. Notice that the array was declared to be of size 3. Why? Because the third element that is 0, 1, 2, the element with index 2 will contain backslash 0. All this has to happen and has to be taken care of by my main program. As far as this function is concerned, I am assuming that the right values for a student come as a part of the structure s. So, just as I have printed s dot name, s dot roll, I can print s dot grade or alternately s dot grade 0 and s dot grade 1 for which the format specifier I will use is c because I am printing a character. Here, I have used s because I am specifying a string. This is merely to tell you that character string arrays can be handled as individual characters or as a collection of characters reprinted by the entire array. Now, my main program starts. This is where I declare the variables or arrays of all the types that I want. Particularly of the structure info, student info type, I want a variable s. I also want an array of 100. Why? Because I might want to put all the students information in an array for a consolidated printing or for any other purpose that I might wish to do. Long end d b file pause. d b file pause is the file position in the database file. What is the file position in the database file? Let me go over to this paper to once again explain that concept. I think I had shown you a diagram earlier. So, let us say star f p is the file pointer which points to this file. File is a sequence of bytes. The kind of file that we are talking about is supposed to contain from the beginning records of the students. So, we will say this is record of serial number 0. This is record of serial number 1. This is record of serial number 2, record of serial number 3, etc. Serial number being an artificial number given to each student. This will contain of course the roll number, name, marks, grades, etc. So, this conglomeration, how many bytes it will have? The bytes that this particular portion will have, the record will have is the size of the structure. That is what is stored here. Where is this located in the file? It is located at the base address or 0th address. So, this I call it base, beginning. Where is the next record located? If 0th record is located as base, the first record that is next record is located as b plus size of strut, size of s. The next one is located as b plus 2 times size of s, etc. So, if I know the record size, I can position my db, I think db file pos is the word that I have used. This is a variable which denotes a position number, a number and notice that this number is declared to be long end because file could be containing very large number of records. So, I do not want to be able to locate or write or read only 200, 300, 5000 or 16,000 records. So, 2 byte numbers, etc. will not work. A long end is the longest possible. Now, here is a question. Given a serial number 0, 1, 2, 3, 4, how do I calculate the file position? The file position I will write here for serial number, the value of pos. For serial number 0, the value of pos would be at the beginning, this one. For serial number 1, the value of pos will be b plus size. For serial number 2, the pointer should be here. So, b plus 2 times the size. So, notice now, I have a direct correlation between serial number and position. If I know the size, I have multiplied by the serial number and add it to the base. Fortunately, the file cause that I have, I do not have to do any addition because I am required to specify the relative position of my position indicator with respect to the beginning of the file only. I can actually specify the position in terms of bytes, number of bytes, either from the beginning or from the current position, etc. But it is always easier to specify the position in a long file from the beginning. So, this is the position after one record, after second, after third, etc. I will keep that in mind while writing my algorithm. So, we go over to this program again. So, this was just the explanation of DB file pause. Just DB file pause, nothing. Care option, care star, n, care star, r, int, i, j, n, etc., etc., different variables that I will use. Integer rake size. This rake size will be equal to the size of my structure. As you can see later, rake size equal to size of s will capture the record size. I am initializing, declaring a filename array and also initializing it. I call it batch input file dot txt. Similarly, I am declaring an array to hold the database filename and I am also initializing it student db dot bit. It is not uncommon that we declare an array to hold a filename, but we collect the value of the filename from the end user. So, if user may want to prescribe that please call my file by such and such name. In which case, we can read the name from the user and open a file with that name. Anyway, these are preliminary descriptions. This is the first important statement where I open the file batch input file for reading. So, notice this file star fp equal to f open filename comma rs. This is the f open statement which will open the file input file. Now I am reading that file. Notice this f scan f. Please note if I was typing the data on keyboard or if I was using input redirection, I would have used scan f. f scan f is exactly same as scan f, no difference except that it reads from the named file rather than from the std in. So, the specification of f scan f apart from the format string %d and the values which have to be read and then for example, it will also have the file point. So, that is the only difference between scan f and f scan f. So, I read this data. Data of so many students in this batch file is a verification statement where I have read n. In our case, n will be 6. So, it will print data of 6 students in this batch file. Now, as long as file pointer is not null means the file has been successfully opened. What do I do? I have to read n students data starting from 0 to n minus 1. I will start reading it from the subsequent records of the same file f scan f f p, but what follows is not just a number as we read from the first record. We know that first record has only number, but each subsequent record has what? It has name, it has roll number, it has hostile. Notice that roll name, roll number and hostile are not defined as independent variables or array. They are instead all declared to be elements of a structure s. s is the variable. So, I say s dot name, s dot roll, s dot hostile. Notice that in scan f and therefore, in f scan f, I am supposed to give the pointers to the locations where the value will be read. So, hostile, s dot hostile is said and s dot hostile. However, most of the my arrays name and roll are arrays. These are character string arrays and I want to read a character string as signified by percentage, percentage. I force this s dot name and cast it as a character pointer, because it is expecting a pointer here. So, cal star s dot name will correctly read the first string as many characters as you have and assign it to name. After having read name, roll number and hostile, for that student, I will now proceed to read the marks. Sorry, not read the marks, but to set the marks to zero. Notice what we said. This is the only data we have which will come from input five. But when we create a record, the record will contain not only name, roll number and hostile, but also marks and grade, which are unknown. So, I am assigning zero to all marks and I am assigning star to the grade. So, s dot grade zero is star, s dot grade one is star and s dot grade two is backslash zero. Remember, always this has been declared as a string, so it must continue to contain a valid string inside. That's it. For i equal to zero to n minus one, I read data for one student, whatever is available. I patch it up with the artificial data for the additional information, which is not available. In this case, I set marks to zero, grade to star star and repeat the situation for as many students as I have. Whether it is six students, it is this six line code segment which will create that five. Whether it is six lakh students, the program will remain the same. At the end of this, I say f close f p, which will close the file. Else comes from where, if file pointer not null, do all of that. That means, if input file could be opened, then we have done all that. But if input file could not be opened, we will say error file name. Notice this is a function, p error file. This is actually an error exit. Otherwise, I say data has been read from batch file. An output binary database file will be created. Size of each record will be rake size, which I have already calculated. Again, to create the database file, it is very simple. For this student, one student I have read, five star d b f open d b five w b. For i equal to zero to n minus one, s is equal to student list i. Remember when I took the data for one student, I have put the value of s into student list i, so that I have all the six student data there. Now, I am writing all of them together. f write, this is the statement I would like you to pay attention to. f write and s, size of struct student info comma one comma d b. f write says what is to be written. So, I am passing the pointer of the structure. This structure contains the data of first zero s student initially, then first student, second student. So, that is the data to be written. How many elements I have to write? Only one element, because I am writing data for only one student. And how many bytes? Size of struct. That is it. This is another way of writing it. Instead of asking machine to re-estimate the size of struct, I know it. I have already calculated it and assigned it to rex size. I can say and s comma rex size comma one comma d. What is forgotten is we have forgotten to close the files. We had opened two files. We had one f close. Fortunately, all files are automatically closed upon normal termination. Secondly, we had a variable declared called option, which is not used anywhere in the program. Why do such things happen? Now, I can tell you why the word option is there. Originally, when we were thinking of developing this program, we said that adding inserting a value, inserting the marks for one test is one option. But another option could be I have already got all the marks. Another option would be to ask the machine to read the marks for all the five tests, give me the total and expect a grade from me, A, B, C, whatever one. So, that could be another option. Now, how do I indicate options? So, I had thought originally that we could write a single program. Given option, say create or option one, it will create the database file come out. Given option two, it will permit me to update marks of a stool. Given option three, it will permit me to insert the grade. Given option four, it will permit me to change the hostel number because a student during the stay may move from one hostel to another hostel. Indeed, that is how real life applications are made. You have some kind of a menu graphically and you say click here to create a database, click here to add marks, click here to do something. As a matter of fact, such are the projects which are often done by groups here, creating a system of programs with such menu choices and so on. With that in mind, I had declared the variable option. Subsequently, while developing the programs, I decided to write two separate programs, but the poor fellow option remained in the program. Now, if you read these programs independently, the word option will strike to you as being odd and I would not be available to explain things to you as I have explained here. The purpose of these deliberations is to indicate that the purpose is to indicate that one should be very careful and therefore, in professional programs, not only you are required to define all the variables as you need, but each variable must be explained as to what is its purpose. If that explanation was given, I myself would have realized that, oh, this is not being used. Another professional way is to ensure that you take all declarations and see whether those declarations are used in at least one executable statement in the program or not. This actually can be done very easily. Many compilers give you this option that whether your code that you have written, does it use all the variables and errors that you have declared or not. Here is a database update program. This update program will be very similar to that in the sense that it will have the definition of that structure. It will have the wide print student function also because I will need to print any student's information. Now, observe how the database is going to be updated. The main program now has all these definitions as usual, the db file position and so on, rex size, etcetera, etcetera. But what does, what it does logically is first now, the database file has been created. So, it will ask for the key value for student. This key value is the serial number. So, by using scanf from the keyboard input, I am collecting from the user the serial number. Then the program ask the user to provide test number and test marks to be updated because our assumption is one test number, one test marks will have to be updated. So, which test? First, second, test, third, test, whatever. Next, now I have got a serial number of the student. What I have to do? Go to the file, read the student's record, replace the zero marks or whatever earlier marks were by the new marks that have been given and rewrite that record exactly in the same place. Exactly in the same place is important. So, what do I do? I first locate the position where the file pointer should be, not file pointer, where the position, where within the file I have to read. db file pos is size of structure of student info multiplied by s n. This is what we had agreed. If the serial number of the candidate is zero, the file position will be zero bytes away from the beginning. If the serial number is one, it will be one size away. If the serial number is two, it will be two sizes away and so on. And with this file position, I say f read, sorry f seek, f seek, f p, db file pos seek set, seek set and seek curve, c u r. This seek set represents from the beginning. Seat curve means seek from the current position. I am using always the references from the beginning. So, this is, you know, file is a sequence of bytes as I said. You are reading it. So, while reading, you may be somewhere here. Now, you may want to prescribe the relative position from the current position saying go to the next byte or go to the next size. Alternately, you can always prescribe the position from the first beginning curve. Where is it advantageous to specify position from the current position when you are reading the data sequentially? So, you got one record. From the current position, you say next record. From the current position plus one size next record. So, you can read them sequentially. When you want to read them randomly, then it is required to specify you read here, you read here, you read here and that position depends upon the serial number. So, we calculate the position as we illustrated earlier and this position is with respect to the beginning of the file. So, from this point, how far away I want to seek? That is why I give this F seek statement. This positions the d b file pass value to the right place and then I say F read. Again F read, I have used here size of struct student info to indicate how many bytes are to be written. I could very well have said the rake size which I had used earlier. So, I read that value and I pass on that structure S. Please note I have passed the pointer and S here. So, I pass on that structure S to the print student function along with that serial number and that fellow will print it. So, what is it printing? It is printing the current value stored in the database for that student's record. Next, I change the test marks. I have already read the test number and test marks. Notice that the test numbers usually will be 1, 2, 3, 4, 5. However, inside the array elements will be 0, 1, 2, 3, 4. So, I subtract 1 from the test number, use that as an index for S dot marks which is an array and allocate rate test marks there. Having done that, I again do an F seek. What do I do? I do F seek with exactly the same value. Why do I have to reset F seek, reset state or re-execute this statement? Well, what happens is when I executed this read, the F seek would have positioned the file for reading at a particular point. When I say F read, it would read one block. Unfortunately, when it reads one block, that position indicator moves away. Now, if I just issue a write, it will write at the next position. I do not want that. So, I bring that fellow back again to where it was originally when I read the record. That is why I need to issue a seek. In general, this is a thumb rule you should tell your students. If you are writing an update program for direct access or for that matter for any access, then you will seek before reading. You must seek again before writing and you seek must be same as you sought or your seek was for reading. So, I seek and read. After reading the data, I again seek and make the file to be positioned there and then write. Write and read are exactly very similar operations. They only have opposite direction. Read will bring data from disk into memory into the structure variable s and write will take the data from structure variable s and write it back into this. And we have ensured that the structure variable s element values have been appropriately changed. Next, I confirm changes in the file. Notice what the teacher told me. Look, this is sensitive information. So, how am I sure that you have not made a mistake? So, I will again seek, read that data and print the student that s and serial number and then I close the file. And just to make sure after every update, I will print the data for all the students here. So, I say fp is equal to f open dv file for reading now. This is the same database file. It was open for reading and writing. Now, it is opened only for reading. And since I know there are six students, I am simplifying it. I equal to 0 to less than 6. Read one by one the student data and print student data. This is my final variable. So, when this program ends, I would have got a print out of the changed value and now I would have got the print out of all the current status of the students here. You can consider several variations of this program. As I said, you can consider building a menu. What we have discussed today is a, perhaps a better way of explaining the notion of a structure. b, use of that structure to represent multiple elements put together as information about a student and this could be done for anything else. And c, we have constructed an example to be shown to first year students where a problem definition is first evolved through a, suppose a dialogue between a teacher and a programmer and then we have discussed the program after describing the programming strategy. I personally believe that this is a good way of explaining things to first year student. Thank you. Over and out.