Lab 5 - File Operations

Click here to CREATE ANSWER SHEET for LAB 5

Objectives:

Sections:
  1. Introduction
  2. Input/Output Concepts
  3. Creating Files
  4. Redirection of I/O
  5. Accessing Data Files for Input using File Functions
  6. Accessing Data Files for Output using File Functions
  7. Reading Character Data with the get function
Introduction
This lab reviews input/output concepts.  In this lab, you will learn to read data from a file and to create a file from a program.  This can be done using redirection of I/O or by file functions to access a file directly from a program.
 

Input/Output Concepts
In previous labs we have only used C++ standard input and output devices to produce solutions to various problems.  Thus the keyboard (standard input) was used to enter the needed data during the execution of the program and the output of the program was displayed on the computer screen (standard output).  In other words, the programmer participated in interactive processing, a type of processing in which the user communicates with the processor during program execution.  There is a second form of processing called batch processing.  Many programs in the "real" world use batch processing. Batch processing uses secondary storage devices (disks or tapes) from which data is obtained for input and may be used to store output data produced by a program.  This type of processing is called batch processing since the user does not communicate with the processor during the program execution.  If a program is executed in batch mode, then, all data could be obtained from a disk and all output could be stored on the disk as well.


Exercise 1:
Write the answers on the answer sheet:
a.  Describe the difference between batch processing and interactive processing.

b.P  (Any question ending in 'P' is a posttest question.  These questions must be done without 
help from your lab instructor or anyone else)  Interactive processing uses secondary storage 
devices (disks or tapes) from which data is obtained for input and may be used to store output 
data produced by a program.  True or false? 




Creating Files
A file is a collection of related data items. You will be working with various files throughout this semester.  You may already be familiar with several different types of files: source files, executable files, etc. Let's look at this simple example of a data file called customers.dat:

        DOE, JOHN
        150.00
        SMITH, JIM
        270.00
        BROWN, CAROL
        800.40
          .
          .
This data file consists of a person's name and charges for services rendered for a particular company. We may create this file using the vi editor in exactly the same manner as we create our source files for our C++ programs. We would type

$ vi customers.dat

and then enter the lines of data exactly as they appear above. Now, when this information is needed by a billing program, we could specify that the computer obtain all needed data from this data file rather than from the keyboard. When the billing program is executed, then, the user is not required to interactively type in the above data - all data is obtained from this data file which permanently resides on a secondary storage device.
 


Exercise 2:
Why might it be beneficial to instruct the computer to obtain needed data in a program from a data file, rather than from the user at run time? Place your answer on the answer sheet.

Exercise 3:
Using the vi editor, create a data file called cla5a.dat which contains the following data:

        150.00    50.00
        270.00    20.00



Redirection of I/O
Data files may also be created by a program. In previous lab exercises the output of a program has appeared on the standard output device, the computer screen. However, often it is beneficial to direct output to a secondary storage device instead, thus creating a data file. We will address this later in the lab.

One way to associate our input and output with a batch data file instead of the standard input and output devices is through input/output redirection using operating system commands. You can instruct your C++ program, say myprog.cpp, to take its input from a file mydata.dat by compiling your program just like normal:

$  c++ myprog.cpp -o myprog

and then when you execute your program, type in the following:

$  myprog < mydata.dat

This statement causes the program myprog to execute and to obtain all input from the file mydata.dat instead of the keyboard.  The symbol "<" tells the operating system to take input from a file.  Since data is read from the file instead of the keyboard, the program need not supply prompting prints. Thus if your program was reading (via input redirection) from the file that you created in Exercise 3, all you would need in your program would be:

cin >> amount;

This would obtain the first value from the file. The value of amount would be 150.00 if this were the first input statement in the C++ program.

Similarly, output may be redirected from the screen to a file, say outfile.dat, by using the operating system command:

$ myprog > outfile.dat

This would cause all output generated by any cout statements to be sent to the file outfile.dat.  The symbol ">" tells the operating system to send output to a file (output redirections).
 


Exercise 4:
Copy the file $CLA/cla5a.cpp to your account. A listing of the program follows this exercise for your convenience.

Write the answers on the answer sheet:

a. Explain the purpose of this program

b. Tell whether this program requires user input at run time

c.P (Notice this is another posttest question) What is the command to perform output redirect given the executable file named "prog5" and the name of the output file called "results5".




     1	//Function:  cla5a.cpp
     2	//Author:
     3	//Purpose:   This program updates a checking account given the
     4	//           starting balance and the amount of the
     5	//           check written against the account.
     6	
     7	//include files...
     8	#include <iostream>
     9	#include <iomanip>
    10
    11	using namespace std;
    12	
    13	//function prototypes...
    14	void PrintStars ();
    15	void Heading ();                                  //display bank heading
    16	void PrintInfo (float old, float amount, float bal);  //display results
    17	
    18	//-----------------------------------------
    19	int main ()
    20	{
    21	     //local declarations...
    22	     float oldBalance,      //starting balance of the account
    23	           check,            //amount of the check
    24	           balance;          //new balance
    25	
    26	     // print a heading
    27	     Heading ();
    28	
    29	     // Input starting checking balance and amount of check.
    30	     cout << endl << "Enter balance from previous month" ;
    31	     cout << " and the amount of check," << endl << "and hit <ENTER>   " ;
    32	     cin  >> oldBalance >> check;
    33	
    34	     //calculate and print the new balance
    35	     balance = oldBalance - check;
    36	     PrintInfo (oldBalance, check, balance);
    37	
    38	     // Input starting checking balance and amount of check.
    39	     cout << endl << "Enter balance from previous month" ;
    40	     cout << " and the amount of check," << endl << "and hit <ENTER>   " ;
    41	     cin  >> oldBalance >> check;
    42	
    43	     //calculate and print the new balance
    44	     balance = oldBalance - check;
    45	     PrintInfo (oldBalance, check, balance);
    46	
    47	     PrintStars ();
    48	
    49	     //end of main...
    50	     return 0;
    51	}
    52	
    53	//-----------------------------------------
    54	//Function:  Heading()
    55	//Purpose:   Print a heading for the bank statement.
    56	
    57	void Heading ()
    58	{
    59	     cout << endl;
    60	     cout << endl;
    61	     cout << endl;
    62	     PrintStars ();
    63	     cout <<"               FIFTH NATIONAL BANK                     ";
    64	     cout << endl;
    65	     cout << "              1515 ONE TIME STREET" << endl;
    66	     cout << "             MANY APPLES, MINNESOTA";
    67	     PrintStars ();
    68	     return;
    69	}
    70	
    71	//-----------------------------------------
    72	//Function:  PrintInfo()
    73	//Purpose:   Print all banking information.
    74	
    75	void PrintInfo (float old,            //IN:  starting balance
    76	                float amount,         //IN:  check amount
    77	                float bal)            //IN:  ending balance
    78	{
    79	     cout << fixed;
    80	     cout << showpoint;
    81	     cout << endl;
    82	     cout << "  OLD BALANCE  CHECK AMOUNT   NEW BALANCE  " << endl;
    83	     cout << endl;
    84	     cout << setprecision (2) << setw (10) << old << setw (15) << amount;
    85	     cout << setw (15) << bal;
    86	     cout << endl;
    87	     return;
    88	}
    89	
    90	//-----------------------------------------
    91	//Function:  PrintStars()
    92	//Purpose:   Print decorative stars.
    93	
    94	void PrintStars ()
    95	{
    96	     cout << endl;
    97	     cout << "********************************************************";
    98	     cout << endl;
    99	}



Exercise 5:
Compile and run the program cla5a.cpp so that you will be familiar with the execution of the program.

    a.  Now redirect the input so that it comes from the file cla5a.dat which you created in Exercise 3.


Note: The program should obtain all input from the file cla5a.dat, and runs without waiting for you to enter any input.

    b.  Now redirect the output to the file cla5a.txt.  Examine the output file by using the cat cla5a.txt command.

Create a script log, called lab5ex5.log of a print, a C++ compile, and a run of these activities by typing

$ script lab5ex5.log
$ pr -n -t -e4 cla5a.cpp
$ c++ cla5a.cpp -o lab5ex5
$ lab5ex5 < cla5a.dat > cla5a.txt
$ cat cla5a.txt
$ exit



Accessing Data Files for Input using File Functions
We now consider a second method of accessing data files for input. Instead of redirecting input, we will directly access the data in an input file. In order to do this, it is necessary to first introduce the concept of the C++ stream. To understand a C++ stream, try to visualize a stream of water flowing toward a nearby lake. Similar to this stream of water, a stream in C++ is a sequence (stream or flow) of characters. Up until now, all input and output has been implemented using the standard input stream (cin) and the standard output stream (cout). Every C++ program has these streams and at least one other, the standard error stream (cerr) available as long as the iostream header file is included. Therefore, C++, sets up a stream from the keyboard so that data may flow from the keyboard to the input request in a given program. We use the extraction operator >> to extract data from the stream. The input statement

char oneChar;   cin >> oneChar;

will examine the input stream from the keyboard, will obtain the next nonwhite space character in the stream and will store this character in memory under the name, oneChar.  If no character is present in the stream, the execution pauses to wait for one. The input statement:

int number1;    cin >> number1;

will examine the input stream from the keyboard for the next integer. In this example, the computer will skip any leading white space, obtain digits from the keyboard until a non-numeric character is encountered, and will store this integer in memory under the name, number1.

In a similar manner, we note that cout sets up a stream to the screen so that the data may flow from memory to the screen. The insertion operator << is used to put data into the stream. Therefore, we see that all input and output operations in C++ are performed using streams. Once the concept of a stream is understood, it is relatively easy to understand the changes that must be made in a C++ program in order to obtain input from another stream, not the standard keyboard stream.

Suppose that we have created a file called cla5b.dat. Also, assume that it contains the following data:

45 52
88 91
This file consists of two lines of two integers each and can be accessed by the following C++ program:


    1	//File:     cla5b.cpp
    2	//Author:
    3	//Purpose:  This program is an example of a C++ program which
    4	//          obtains input to the program from a file rather
    5	//          than from the keyboard.  It will read integers
    6	//          from a file called cla5b.dat.  The program will
    7	//          then output the integers to the screen.
    8	
    9	#include <iostream>
   10	#include <fstream>
   11	#include <iomanip>
   12	
   13   using namespace std;
   14	
   15	int main ()
   16	{
   17	     //local declarations...
   18	     ifstream myin;         //input file stream
   19	     int number1, number2;  //variables to hold integers read
   20	
   21	     //prepare file for reading and identify external file
   22	     myin.open ("cla5b.dat");
   23	
   24	     //read two data sets
   25	     myin >> number1 >> number2;
   26	     cout << "Line " << 1 << ": " << setw(7) << number1;
   27	     cout << setw (7) << number2 << endl;
   28	
   29	     myin >> number1 >> number2;
   30	     cout << "Line " << 2 << ": " << setw(7) << number1;
   31	     cout << setw (7) << number2 << endl;
   32	
   33	     //end of main...
   34	     return 0;
   35	}

There are several directives which must be included in a C++ program in order to access a data file. They are shown in bold above. The above program demonstrates that we must:
Exercise 6:
a.P Given the declaration 
		ifstream myin; 
    write a statement to prepare (open) the file "input.dat" for reading in the answer sheet.
b. Copy file
cla5a.cpp to lab5ex6.cpp Make all necessary changes in lab5ex6.cpp so that data is obtained from the data file called cla5a.dat which you created in Exercise 3. Do not use redirection of input. Instead, add statements to your C++ program so that each input item comes from the file by using file functions.

Exercise 7:
Create a script log, called lab5ex7.log of a print, a C++ compile, and a run of these activities by typing

$ script lab5ex7.log
$ pr -n -t -e4 lab5ex6.cpp
$ c++ lab5ex6.cpp -o lab5ex6
$ cat cla5a.dat 
$ lab5ex6 
$ exit
Do not proceed to the next step until this program executes properly!

Accessing Data Files for Output using File Functions
We indicated earlier in this lab that a text file may be created by the user or by program output. This can be accomplished by allowing a C++ program to send output to a file rather than to the screen. We mentioned that data could be sent to an output file by using redirection. It can also be sent to an output file directly, which is the subject of this section.

The following program creates a permanent file called cla5c.dat.


    1	//File:    cla5c.cpp
    2	//Author:
    3	//Purpose: This program will read in names and phone numbers.
    4	//         It creates a permanent file called cla5c.dat
    5	//         on the disk in the default drive.  The program will
    6	//	   will read two sets of records and store them in the file.
    7	
    8	//include files...
    9	#include <iostream>
   10	#include <fstream>
   11	#include <string>
   12
   13   using namespace std;
   14	
   15	int main ()
   16	{
   17		//local declarations...
   18		ofstream outData;		//output file stream
   19		string phoneNumber;
   20	
   21		//prepare file for reading and identify external file
   22		outData.open ("cla5c.dat");
   23		string name;			
   24	
   25		//get a name and phone number, and put them in the file
   26		cout << endl;
   27		cout << "Please enter a last name and phone number, ";
   28		cout << "and hit <ENTER>. " ;
   29		cin >> name ;
   30		cin >> phoneNumber ;
   31		outData << name << " : " << phoneNumber << endl;
   32		cout << name << " : " << phoneNumber << endl;
   33	
   34		//get another name and phone number, and put it in the file
   35		cout << endl;
   36		cout << "Please enter a last name and phone number, ";
   37		cout << "and hit <ENTER>. " ;
   38		cin >> name ;
   39		cin >> phoneNumber ;
   40		outData << name << " : " << phoneNumber << endl;
   41		cout << name << " : " << phoneNumber << endl;
   42	
   43		//end of main...
   44		return 0;
   45	}
The method used for writing data to a file is very similar to the standard output discussed in earlier labs. As a review, note that the statement:
cout << "HELLO" << endl;

sends the string of characters "HELLO" to the standard output stream, usually the screen. The statement,

outData << "HELLO" << endl;

will send the string of characters "HELLO" to the stream called outData which we have defined to be an output stream corresponding to a file called cla5c.dat in the above program.


Exercise 8:
a.P  Given the declaration 
		ofstream myOut; 
    write a statement in the answer sheet that prepares (open) the file "output.dat" for writing.

b. Copy the file
$CLA/cla5c.cpp to your account and add code so that a person's age is read from the keyboard and stored permanently in the file. Be sure to use the endl in the right place (after the person's age) so that the file contains one record (name, phone number, and age) on each line.

Exercise 9:
Compile and execute the revised
cla5c.cpp program. During execution, type in your name, phone and age.
Create a script log, called lab5ex9.log of a print, a C++ compile, and a run of these activities by typing

$ script lab5ex9.log
$ pr -n -t -e4 cla5c.cpp
$ c++ cla5c.cpp -o lab5ex9
$ lab5ex9 
 ... enter your name, phone, and age here ...
$ cat cla5c.dat 
$ exit

Reading Character Data with the get function
We have used the extraction operator ">>" to read a value from an input stream.  When looking for the input value in the stream, the extraction operator skips any leading white-space characters. White-space characters are the characters such as blank (' '), tab ('\t'), and new line characters('\n').  Once a non-white space character is reached, the operator extracts a value from the input stream.  If the variable type is char, input stops as soon as a single character is read.  If the variable type is int or float, input stops at the first character that is inappropriate for the data type, such as a white-space or a non-digit character.

Suppose that we have asked a user to enter a telephone number for a program.  A user may enter a telephone number in different formats: 615-555-1234, (615) 555-1234, or 615 555-1234.  The following program tries to handle different cases using the get function.  The get function reads the very next character in the input stream without skipping any whitespaces.  A get function call looks like this:

cin.get(letter);
The get function is associated with an istream data type (cin in this example).   You must use dot notation to make the function call. The argument of the get function is of char type.  The character read by the get function will be stored in the variable used as the argument.



     1  //File:     cla5d.cpp
     2  //Author:
     3  //Purpose:  This program will read a telephone number and separate it
     4  //          into area code and local codes.
     5    
     6  #include <iostream>
     7  #include <string>
     8
     9  using namespace std;
    10    
    11  int main ()
    12  {
    13      //local declarations...
    14      int areaCode;                // area code
    15      int localCode1, localCode2;  // local codes
    16      char letter;                 // character used for separator
    17      string firstName;            // string for the first name
    18      string lastName;             // string for the last name
    19    
    20      // read name
    21      cout << "\nPlease enter your name :";
    22      cin >> firstName >> lastName;
    23      cout << "Thank you, " << firstName << ".\n";
    24    
    25      // read telephone number
    26      cout << "\nPlease enter a telephone number including area code:";
    27      cin >> areaCode;
    28      cin.get(letter);
    29      cin >> localCode1;
    30      cin.get(letter);
    31      cin >> localCode2;
    32    
    33      // print out the name and the telephone number
    34      cout << endl << endl
    35           << firstName << " " << lastName <<"\'s telephone number : ("
    36           << areaCode <<") " << localCode1 << "-"<< localCode2
    37           << endl << endl;
    38    
    39      //end of main...
    40      return 0;
    41  }

Using the function get(), whitespace characters are treated just like all other characters. Thus when a blank or a newline is encountered in the input stream, it is read from the stream just like any other character.  Notice that the program used an escape sequence \n to generate a new line and \' to print an apostophe.
 


Exercise 10:
a.P  Given the following input data: 
A 3KC# 
What values are read into ch1 and ch2 by the following code? 
	char ch1, ch2; 
	cin.get(ch1); 
	cin.get(ch2);

    a. ch1 = 'A', ch2 = ' ' 
    b. ch1 = 'A', ch2 = '3' 
    c. ch1 = '3', ch2 = 'K' 
    d. None of the above 

b. Copy the file
$CLA/cla5d.cpp to your account and add code so that the output is also stored in a file called cla5d.dat. (That is, in addition to displaying on standard output, you should also store the information to the cla5d.dat file.)

Exercise 11:
Compile and execute the revised
cla5d.cpp program. During execution, type in your name and phone number. Run the program with two different phone number formats such as 615-898-2397 or 615 898-2397.
Create a script log, called lab5ex11.log of a print, a C++ compile, and a run of these activities by typing

$ script lab5ex11.log
$ pr -n -t -e4 cla5d.cpp
$ c++ cla5d.cpp -o lab5ex11
$ lab5ex11
 ... enter your name, and a phone number here ...
$ cat cla5d.dat 
$ lab5ex11
 ... enter your name, and a phone number here ...
$ cat cla5d.dat 
$ exit

Exercise 12:

Submit the log files you have created in Lab 5 typing

          $ handin lab5log lab5ex5.log lab5ex7.log lab5ex9.log lab5ex11.log
Exercise 13:

From the PC you are working on, you must also submit the answer sheet (AnswerSheet5.pdf) using the following directions:

  • Save your Lab4 Final Answer Sheet (click icon on very bottom of the answer sheet window)
  • Create the file AnswerSheet5.pdf using your Browser's 'Save as PDF' feature
    (1. ctrl+p [Windows] or command+p [Mac]    2. Select 'Save as PDF')
  • Use your C-number/password to log into the Gus Homework Repository System:
    https://www.cs.mtsu.edu/cgi-bin/gus/gus.py
  • Submit your AnswerSheet5.pdf file to the Gus Homework Repository System
    1. Select the assignment from the dropdown menu: lab5ans
    2. Select the Submit radio button
    3. Click the button: Perform Action
    4. (On the subsequent screen) Click the button: Choose File to locate your AnswerSheet5.pdf
    5. Click the Upload button to upload the chosen file.

Congratulations! You have finished Lab 5.



Once you are done, you will need to log off ranger. Enter   $ exit   to exit the (sakura) terminal window. Depending on how you logged in to ranger you will need to enter $ exit one or more times to get completely logged off the system.