CS 70

Reading User Input

While output is written to an ostream such as cout or cerr, input is read from an istream such as cin. Reading text from the user for this assignment will require you to use several C++ I/O features. Most of these features are enabled via #include <iostream>.

In the asciimation assignment, you read characters from a file to load your Sprites using code similar to

char nextCharacter;
while (cin.get(nextCharacter)) {
    // ... do stuff with nextCharacter
}

In this code, the loop exits when there are no more characters available on cin—when EOF (end-of-file) was hit. Note that EOF is not the same as the end of a line.

I/O Redirection

One way to get input to cin for your program is to do I/O redirection on the command line. For example,

./program < my-input-file.txt

will redirect the contents of my-input-file.txt to the cin of program. program does not have to deal with (and will never see) the I/O redirection part of the command line, as that operation is performed by the Unix shell before your program is executed.

Reading Files in Your Program

You can also write code that will read data directly from a file whose name is provided to your program on the command line at runtime. It's more complicated than just reading cin, but it also gives you way more control and flexibility than the simpler method.

In your code, you need to #include <fstream>. Then you write code that opens the file, reads the file, and closes the file when you're done. In C++, doing so is easy: you open a file by creating an ifstream (for reading) or ofstream (for writing). The file is automatically closed when the associated ifstream or ofstream is destroyed.

Once you have created an ifstream, you can read from it just as if it were cin.

To make this explanation more concrete, suppose you want to read characters from a file named myfile.txt. You could write some code like

ifstream inputStream("myfile.txt");
if (!inputStream) {
    // ... Oops, myfile.txt doesn't seem to be available!
}

char nextCharacter;
while (inputStream.get(nextCharacter)) {
    //... do stuff with nextCharacter
}

In most cases you won’t want to hardwire the filename into your code, of course. (Even if you did, that filename would count as a magic string, so it should be defined as a const string rather than just popping it directly into your code.)

Here is a similar example with a filename provided in a variable:

bool readFile(const string& whichFile)
{
    ifstream inputStream(whichFile);
    if (!inputStream) {
        return false; // Couldn't open file
    }
    char nextCharacter;
    while (inputStream.get(nextCharacter)) {
         // ...do stuff with nextCharacter
    }
    return true;
}

The filename is provided via a const string& variable named whichFile, passed as a function argument. This function returns true if the file was successfully read.

(When logged in, completion status appears here.)