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 Sprite
s 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.)