14.8.2. s-rolodex.cpp: string Class I/O Example

The first solution for the Rolodex problem is based on the C++ string class. Furthermore, it's much easier to test the program as we write it rather than waiting until it's finished. If we test the program throughout development, we know that any new problems are likely to be in the newest code added. That means that there are fewer places for bugs to hide. Once we verify a logical group of statements, we can rely on the following code more confidently.

Do this part before copying rolodex.txt into the project folder.

The first step is opening the file and detecting when an error occurs. We write just enough code to complete these two tasks.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;


int main()
{
	ifstream in("rolodex.txt");

	if (!in.good())
	{
		cerr << "Unable to open \"rolodex.txt\"\n";
		exit(1);
	}

	return 0;
}
s-rolodex.cpp (Version 1). Although this code is incomplete and doesn't solve the overall Rolodex problem, it is complete enough to compile and run. Running the code before we copy rolodex.txt into the project folder allows use to test the if-statement - it's important to test the code that verifies that the file was opened correctly.
Now, copy rolodex.txt into the project folder.

Parsing input is a rather complex and error-prone operation. If there is a problem with the program, it would be a shame to focus our attention on the parsing operation only to discover the problem was in the code reading the file. So, we write code that demonstrates that the program can read the file. However, this code is NOT part of the final program and must be removed or commented out of the final program.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;


int main()
{
	ifstream in("rolodex.txt");

	if (!in.good())
	{
		cerr << "Unable to open \"rolodex.txt\"\n";
		exit(1);
	}

	string	line;

	while (getline(in, line))
		cout << line << endl;

	return 0;
}
s-rolodex.cpp (Version 2). A simple while-loop reads each line of text from the file and echoes it to the console: the program output looks exactly like the input file without any parsing taking place. If we see the input file contents echoed to the screen, we can proceed with confidence; otherwise, we must look for a logical error before proceeding. Aside from verifying that the program can read from the input file, this while-loop also demonstrates how to read and write files one line at a time when little processing is needed.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;


int main()
{
	ifstream in("rolodex.txt");

	if (!in.good())
	{
		cerr << "Unable to open \"rolodex.txt\"\n";
		exit(1);
	}

	/*string	line;

	while (getline(in, line))
		cout << line << endl;*/

	while (!in.eof())				// (a)
	{
		string	name;				// (b)
		getline(in, name, ':');			// (c) - 3-arguments
		cout << left << setw(20) << name;	// (d) & (f)

		string	address;			// (b)
		getline(in, address, ':');		// (c) - 3-arguments
		cout << setw(35) << address;		// (d)

		string	phone;				// (b)
		getline(in, phone);			// (e) - 2-arguments
		cout << setw(20) << phone << endl;	// (d)
	}

	return 0;
}
s-rolodex.cpp. In the final, complete version of the program, the test loop is commented out and replaced by the "real" processing loop.
  1. Keep looping while not the end of file
  2. Define a string variable to hold part of the input
  3. Reads text from the input stream in, stores the text in the string variable, and stops reading when the delimiter (the third argument, the colon character in this example) is encountered. Discards the colon.
  4. Prints formatted output on the console
  5. Notice that the program uses the two-argument version of getline to read the last field. Reads text from the input stream in, stores the text in the string variable, and stops reading when the new line is encountered. Discards the new line.
  6. The left manipulator causes the output be be left justified in the space allocated by the setw manipulator; notice the order of the two manipulators - it is important

Downloadable File

s-rolodex.cpp