Repetition Using the End of File Condition Quick Start Compile step once always g++ -o Scan4 Scan4.cpp mkdir labs cd labs Execute step mkdir 4 Scan4 cd 4 cp /samples/csc/155/labs/4/*. Submit step emacs Scan4.cpp & submit csc155abc 4 Problem Statement and Specifications This assignment continues our study of string and double objects as well as the use of input files. This program will use repetition, but not selection. Files come in two varieties: sequential access files and direct access files. Basically, the files used in this course (for input, output or source code) are sequential access files. These files have their data separated into records or lines and we process the records (lines) in the order in which they are stored. Databases use direct access files. These files have their data separated into records, but we access the records in a random order. Think of the database that contains student data for enrollment at our school. The staff member at the registration window has no knowledge of how registrants will approach the window, and so the records in the database are accessed in an unpredictable order. The means by which we implement these features into our files is that with direct access files, we require that every record be the same size. Since this must be large enough to accommodate the largest record, each record must be the same size as the largest record regardless of how much or how little data is stored in that record. Sequential access files do not require this feature, so every line in our input or source files can have a different length than every other line. Direct access files are beyond the scope of our course, but databases are the original computer application and they have continued to play an important role in computing from its earliest days to the present. Assignment 4 Statement: Write a program in a file named Scan4.cpp that reads the inventory for a hardware store from a sequential access file named scan.txt. Each line of the input file contains a string and a double separated by a blank character (you are guaranteed that the string has no embedded blanks). The string value should be interpreted as the name of a tool and the double value should be interpreted as the price of that tool. Your program should display each line of the file on the monitor using appropriate formatting. When all of the lines of the file have been processed, display the total number of tools in the file and the sum of all of the costs for all of the tools that were stored in the file. All output for this program should be displayed on the monitor. Since the input string will not contain embedded blanks, we can use the usual input operator ( >>) for input from scan.txt. Associated with this solution is the use of a List Reduction Algorithm that takes a list of 1
numbers and accumulates them one at a time. The algorithm requires a repetition structure so that we can visit every element in the list. It can be described in the following steps. I. initialize an accumulator to 0 II. loop to visit each list element III. update the accumulator as you visit each list element We ll use this algorithm to accumulate the double value that is stored on each line. Assignment 4 Specifications: Input Read a tool name and a tool cost from the input file scan.txt Output Display on the monitor the tool name and tool cost for each input line Output Display on the monitor the total number of tools and the total costs of all the tools Object Analysis and Algorithmic Development We ll need at least a string and a double object to read the data in from the file. In addition, we ll need an ifstream to connect to our input file. Finally, we ll need another double to accumulate the tool prices that are stored in the file as well as an int to accumulate the number of tools in the file. Let s start our algorithmic development at the usual place. 1. Input 2. Process 3. Output We ll need to do some preparation for the input in that we ll need to connect to the file and we ll also need to initialize our accumulators for the List Reduction Algorithm described above. In order to process every line within the file without knowing how many lines are in the file, we ll need to implement an end-of-file loop. This is accommodated by attempting to read the first line of the file and then entering a loop that is controlled by the ifstream.eof() function. Within that loop, we ll need to update our accumulators and display the current input line before we attempt to read another line from the file. After the loop, we simply display our accumulators with appropriate labels. Our algorithm is looking like the following sequence. 1. process initialize file and accumulator variables 2. output display a descriptive message about the program and the output headings 3. input attempt to read the string of the first item of the file 4. process determine if the end-of-file condition is true (a) input read the double value cost from the current input line (b) process to update the total cost of the tools (c) process to update the total number of tools (d) output display the tool name and cost for the current line (e) input attempt to read the string of the item from the next line of the file 2
5. output the total cost and the total number of tools in the file 6. process disconnect from the input file Steps 4.(a), through 4.(e) are indented since they will be repeated for each line of input in the file scan.txt. Our final algorithm, with some renumbering, will look like the following. Note that lines in blue represent areas of code that require you to modify or write code to complete the assignment. Statement Data objects 1) connect the input file object to scan.txt ifstream objects and string constants 2) initialize accumulators to 0 double and int objects and constants 3) display a descriptive message and headings string constants 4) attempt to input the first tool name from the file ifstream & string objects 5) test the ifstream.eof() condition bool method and ifstream object 6) input the cost from the file ifstream & double objects 7) update the total cost double objects 8) update the total number of tools int object and constant 9) display the current tool and its cost ifstream, string and double objects and string constants 10) attempt to read another tool name ifstream & string objects 11) display the total number of tool costs and the total double and int objects and string constants number of tools 12) disconnect from the input file ifstream object and close() method Just to clarify matters, Step 6 through Step 10 are in the while loop determined at Step 5. Coding for Compilation Logon to your csc.oakton.edu account and create a new subdirectory of the labs directory called 4 to work on your assignment. cd labs mkdir 4 cd 4 The documentation for this algorithm has already been included in the file /samples/csc/155/labs/4/scan4.cpp that you can copy over to your local directory by issuing the following cp command. cp /samples/csc/155/labs/4/scan4.cpp. emacs Scan4.cpp & Declaration of Variables The declarations of the string, double and int variables is pretty straight forward. When it comes to the ifstream objects, we ll delve into that as we discuss the pseudo-code. Follow the Pseudo Code Step 1 // connect the input file object to scan.txt We have two options within C++ for this. The first is called the initialization at declaration mechanism where we initialize the ifstream object at its declaration. This would appear as follows. 3
ifstream fin("scan.txt"); The other option would be to declare the ifstream object and then use the ifstream.open() method to connect to the file. ifstream fin; fin.open("scan.txt"); Code one, but not both, of these options in your program before continuing. Step 2 // initialize accumulators to 0 These are simply two assignment statements, one of which initializes the double accumulator to 0.0 and the other initializes the int accumulator to 0. Code these statements before continuing. Step 3 // display a descriptive message and the headings These are simply a output statements that describe the program as is displayed in the sample output. You should also include the headings for the data that will be printed out in the input loop at Step 5. Code these statements before continuing. Step 4 // attempt to input the first tool name from the file Each line of the input file scan.txt separates the string tool name from the double tool cost with the char value of a blank, ( ). There is a guarantee in this program that the tool s item name will not contain any embedded blanks. Anything after the blank ( ) is then guaranteed to be the cost of the item. So, our goal is to read either character data until we reach the char value of assuming that everything that was read represents the tool name. The means by which we can do this from the file is with the usual input operator >> as this does not read blanks and will stop an input operation whenever it encounters white space (i.e. a blank ( ), tab ( \t ) or newline ( \n )). We need not bother to attempt and read the cost since whenever there is an input line, any cost will be preceeded by an item. The failure of the input operation of the item will be sufficient to set the end of file bit used to determine whether there are remaining lines to process in the file. Code this statement before continuing. Step 5 // test the end of file condition The style of loop that we re interested in using at this point in our algorithm is referred to as a while statement and it has some features that are particularly attractive for this exercise. It s general format is the following. while ( bool expression ) { statement 1 ; statement 2 ; }. statement m ; 4
It is assumed that the bool expression is initialized before the loop (in our algorithm, this is Step 4) and is updated somewhere within the middle of the loop (in our algorithm, this is Step 10). This statement will continue to loop as long as the value returned from bool expression is true. The next 5 steps of the algorithm should be embedded within this loop. Steps 6 // input the tool cost These step is simply an input operation from the file using the traditional input operator >> into the double variable that will contain the cost of the tool. Code this input statement before continuing. Steps 7-8 // update the total cost // update the total number of tools These update operations simply increase the double accumulator by the cost of the current tool and increase the int accumulator by 1. Code these assignment statements before continuing. Step 9 // display the current tool and its cost This is simply a formatted output statement that displays the current tool and the current tool s cost. Code this statement before continuing. Step 10 // attempt to read another tool name This line is no different than the line that was written for Step 4. This is the final statement that is embedded within the loop that was started at Step 5. Code this statement before proceeding. Step 11 // display the total number of tools and the total of the costs of the tools This is a formatted output statement that displays the accumulators that were updated at Steps 7-8. Examine the sample output to inspect a full credit solution. Step 12 // disconnect from the input file The ifstream objects support a function that represents the correct means to disconnect from a file. This is more important for output files as we often need to flush data from the logical buffer into the physical file before we disconnect. However, it is good form to do so when we are done with our files. The following statement should be coded before the end of your program. fin.close() Checkpoint We re done, at this point, so save your program to disk by choosing the Save command from the Files menu of your emacs session. Then, compile your program by choosing the Compile... command from the Tools menu and change the make -k that is displayed to g++ -o Scan4 Scan4.cpp. Compiler errors can be parsed with the keystroke C-x and need to be repaired before your program can execute. When your program has compiled, 5
click on your xterm window to access your command line prompt, and issue the command Scan4. Once again, your output should be identical to the sample output. Testing for errors The types of errors that can occur in this program have to do with either the input or the updates to the accumulators. The most common type of error is misspelling the name of the input file scan.txt when the ifstream object fin is initialized. You might also want to use the ls command to make sure that scan.txt is in the directory that your working in. This should have happened when you issued the following command. cp /samples/csc/155/labs/4/*. We ve displayed this statement in red to indicate that you do not want to issue it more than one time. If your input file scan.txt is not in your current directory, issue the following command. cp /samples/csc/155/labs/4/scan.txt. Other areas where errors can occur have to do with the inappropriate placement of the input statements or the incorrect updates to the accumulator variables. Make sure that your code follows the algorithm that we ve discussed to correct any logic errors. Printing and submitting Once you are satisfied with the correctness of your program, print it as you did with previous assignments by using the following command that assumes that you are working in the room 1234 at Oakton. Retrieve your copy from the printer. printer 1234 Scan4.cpp Finally, submit your program with the following command that assumes that you are registered in section abc of CSC 155. submit csc155abc 4 6