PHYCS 3730/6720 Lab Exercise

Reading and references:
Answer file lab17.
Here we learn more about I/O streams in C++. Specifically, how to read a file and check for an end-of-file or error condition, and the difference between standard error and standard output.

Exercise 1. Checking for EOF and errors on standard input

Sometimes it is useful to read a set of values on standard input even if you don't know how many there are. To do this, you need a way to stop reading when an end-of-file is reached. If you are typing the values in on the keyboard, you signal and end-of-file by typing C-d. If you are redirecting from a file, the end of file condition occurs when you run out of things to read. With the istream class the cin.eof() function returns true when the previous read operation encountered an end-of-file. Also, if there is a problem in converting the input string to a number, it is important to know how to check for such a condition. So here is an example. Let's call it dataread.cc.
   #include <iostream>
   #include <vector>
   using namespace std;
     ...
   vector<float> x;
   float xtmp;
   int i,n;
     ...
   while(1){
     cin >> xtmp;
     if(cin.fail()){          // Check for error.
        if(cin.eof())break;      // Check for end-of-file
        cerr << "Error converting input data item.\n";
	exit(1);
     }
     x.push_back(xtmp);
   }

   n = x.size();
   cout << "There are " << n << " data points:\n";
   for(i = 0; i < n; i++){
      cout << "x[" << i << "] = " << x[i] << "\n";
   }
In this loop each value is appended to the vector. The cin.eof() function returns true when an end of file condition is reached. Notice that we test after reading, and if an end of file has been encountered, no value was read. Notice that we protect ourselves from errors in data format conversion by using cin.fail(), which returns true when an error occurred (e.g. nonnumeric characters in the input) or an end-of-file was reached.

The exercise for you is to complete the code above, compile it, and test it on both keyboard and file input. (For file input, just use input redirection with <). Create a file called data for redirection from standard input. Try entering nonnumeric values in place of numbers to see what happens.

Hand in your code and say what happens when you enter nonnumeric values.

Exercise 2. Unix standard error device

Unix recognizes three standard file streams: standard input, standard output, and standard error. The latter are only for output. With the iostream header you access standard input with cin, standard output with cout and standard error with cerr. The standard error stream is typically used for error messages. If you are taking output on the screen, messages written to either standard error or standard output will appear on the screen. But you can separate them by redirection. In the example of exercise 1 we chose to write the data format error message and full array warning message to standard error. Try running the program, but redirecting the output to a file and putting a nonnumeric character in the input to see what happens. You should find that the error message appears on the screen and not in the file that captures only standard output.

If in completing the code in Exercise 1, you thought to prompt the user for input, you might consider that it would be better to send those prompts to cerr, rather than cout so if the user is redirecting output to a file, he/she would still see the prompts on the screen. So it isn't only error messages that should go to standard error.

In the answer file, explain where the error message appears when you redirect standard output to a file or pipe.

Exercise 3. Reading from a specific file

Suppose we created a data file called data and wanted to take input from that file, rather than from standard input. How should that be done in C++?

The online notes show how to do it with the standard header fstream. Modify the code you created in Exercise 1 so you read from the file.

If you want to see my example, see ~p6720/exercises/file_io/fileread.cc, but try to do it yourself first.

Hand in your version of the code.