Program — Vector and i/o stream exercises
This programming assignment gives you practice with vectors (similar to arrays in other languages), files, and string streams in C++, and incidentally exposes you to structs (special kinds of classes) as well.
Readings
A Computer Science Tapestry, sections 7.4, 7.4.1, 8.1 through 8.3, 9.1 through 9.3, 11.1, and 11.5. Astrachan's sections 9.2.2 and 9.2.3 contain the only good explanation of string streams among the three CS 9F textbooks. Astrachan's tvector class is just like the builtin vector class except that it incorporates checks for out-of-range subscript values. He only covers two-dimensional vectors in the context of more advanced material.
C++ Program Design, sections 5.6 (files) and 6.7 (minimal coverage of string streams) plus chapter 10. C-style arrays are forbidden in CS 9F; thus you should ignore declarations in sections 10.2 and 10.12, instead using the vector class to build a two-dimensional structure.
Computing Fundamentals with C++, chapters 9 (files), 10 (vectors), and 19 (two-dimensional structures). Also skim chapters 12 and 13. Mercer does not cover string streams, and mentions structs only in the context of more advanced material. We don't use his matrix class; use vectors of vectors instead.
The section "Linker errors" in this document.
Related quizzes
Programming assignment
Do all three of the programming exercises described on the following pages. Exercise 2 uses a modified form of the solution to exercise 1.
Vectors and i/o streams exercise 1
Practice with files and string streamsComplete the program ~cs9f/lib/p3.1.cpp so that the program repeatedly recognizes and processes the commands from the following list.
update word number list names list quantities batch file-name quitEach legal command must appear on a single line, and have the correct number and type of arguments. The update command must be followed by a word—a sequence of nonblanks—and an integer, with no other nonblank characters on the line. The list command must be followed by either the word names or the word quantities. The batch command must be followed by the name of an existing file. The word quit must appear by itself on the line.
For an illegal command, merely print an informative error message to cerr. For one of the commands update or list, merely echo the command and its arguments. (You don't need to maintain any actual inventory—you do that in exercise 2.) For the quit command, terminate the program using the one-argument exit function declared in <cstdlib>. For the batch command, do the following: read, recognize, and process commands from the specified file, then (assuming that a quit command has not been read) resume reading commands from cin. Assume that the file does not contain any batch commands.
Miscellaneous information
You should fill in the blanks in the InterpretCommands function given in ~cs9f/lib/p3.1.cpp, according to the accompanying comments, and supply definitions for the other Interpret... functions. Don't change any of the existing code. To analyze each input line, read it using a line-getting function described on the previous page, convert it to an input string stream, and then extract its contents using >>.
The easiest way to get information about the success or failure of an input operation—the method we want you to use for this assignment—is merely to test the result of the input extraction. For example,
string s; int k; if (cin >> s >> k) { // string and integer values were successfully read } else { // string and integer values were not successfully read }Passing stream arguments by value rather than by reference often leads to incomprehensible error messages; try to remember not to pass streams by value.
An input string stream provides a way to use the input extraction operator ("<<") and associated type checking and error handling with strings. The Mercer and Cohoon and Davidson textbooks unfortunately contain little or no coverage of string streams. However, an input string stream is invaluable for processing command-line input, and output string streams have interesting uses as well. Here's an annotated function that reads a line from cin and returns true if it contains exactly two integers.
bool ContainsExactly2Ints ( ) { string line; getline (cin, line); // read the line istringstream in (line.c_str()); // initialize a string stream to contain // the same things as line int val1, val2; string temp; if (in >> val1 >> val2) { return !(in >> temp); // we have at least two ints; // make sure that's all we have } else { return false; } }Both the istringstream and the ifstream constructors require C-style strings as arguments rather than string objects. The c_str string member function used in the example above returns the C-style string corresponding to a string object.
The name of the string stream library has changed over the years. The current library name is sstream:
#include <sstream>If you're using an old C++ compiler, you might need to use
#include <strstream>More requirements
Your test cases should include at least one legal instance of each command, provided both in cin and in the batch file. You should also test illegal commands:
a line with a correct command word and the correct number of arguments, but with an argument of the wrong type (word instead of number).
Checklist
- Correct implementations of the Interpret... functions, with no changes to existing code other than filling in blanks.
- Sufficient testing, with output sufficient to verify test correctness:
- tests with all legal commands, both in and out of a batch file (except the batch command);
- tests of illegal commands as specified (blank line, correct command word but too many and too few arguments, correct command word and number of arguments with an argument of the wrong type);
- tests sufficient to exercise all statements in the program.
- Printed listings of program text, tests, and test results.
- Adherence to CS 9F style standards:
- appropriate use of indenting and white space;
- avoidance of "forbidden C++";
- variable and function names that reflect their use;
- informative comments at the head of each function;
- no routine more than twenty-four lines of code.
- Clean case analysis and simple loop structuring.
Program framework (~cs9f/lib/p3.1.cpp)
#include <iostream> #include <fstream> #include <sstream> #include <string> using namespace std; void InterpretCommands (istream&); void InterpretUpdate (istream&); void InterpretList (istream&); void InterpretBatch (istream&); void InterpretQuit (istream&); void InterpretCommands (istream& cmds) { string line, cmdWord; ____________________________ ; // other definitions go here while ( _____________________ ) { // get a line istringstream lineIn (line.c_str()); if ( _____________________ ) { // get the line's first word ___________________________________ // there weren't any words } else if (cmdWord=="update") { InterpretUpdate (lineIn); } else if (cmdWord=="list") { InterpretList (lineIn); } else if (cmdWord=="batch") { InterpretBatch (lineIn); } else if (cmdWord=="quit") { InterpretQuit (lineIn); } else { cerr << "Unrecognizable command word." << endl; } } } int main () { InterpretCommands (cin); return 0; }Vectors and i/o streams exercise 2
Practice with vectors of structsDesign an Inventory class that keeps track of an inventory of donated items. Each entry in the inventory has a name and a quantity. The Inventory class has four public member functions, as declared in the file ~cs9f/lib/inventory.h:
- a constructor, which creates an empty inventory.
- void Update (string item, int amount)
adds amount to the quantity of the named item in the inventory, or inserts the item into the inventory with the given quantity if it's not already in stock. Quantities in the inventory are allowed to be negative.- void ListByName ()
prints inventory entries—name plus quantity—sorted alphabetically by name.- void ListByQuantity ()
prints inventory entries—name plus quantity—sorted in increasing order by quantity.Thus the inventory is maintained only in memory, and has no external file counterpart.
Miscellaneous requirements
Maintain the inventory as a vector of structs. Your inventory class should be able to handle any number of items. If an update would cause the inventory to overflow, it should be expanded to make room for the new item.
Your program must support all the commands described in vector exercise 1.
Test your code by combining it with a modified version of the program from vector exercise 1. Your tests should collectively do the following:
Sorting routines are described in sections 11.1 and 11.5 of A Computer Science Tapestry, sections 10.4 and 10.7 of C++ Program Design, and section 10.5 of Computing Fundamentals with C++.
Checklist
- Correctly working code.
- Sufficient testing, with output sufficient to verify test correctness:
- tests in all specified categories;
- tests sufficient to exercise all statements in the program.
- Printed listings of program text, tests, and test results.
- Adherence to CS 9F style standards:
- appropriate use of indenting and white space;
- avoidance of "forbidden C++";
- variable and function names that reflect their use;
- informative comments at the head of each function;
- no routine more than twenty-four lines of code.
- Clean case analysis and simple loop structuring.
inventory.h
#include <vector> #include <string> class Inventory { public: Inventory (); void Update (string item, int amount); void ListByName (); void ListByQuantity (); private: // You provide this. };Vectors and i/o streams exercise 3
Practice with vectors of vectorsIn a game like chess or checkers, the game board is normally placed between the players, and they sit on opposite sides. Thus, the two players see the board from different perspectives. Opposite views of a 3-by-3 tic-tac-toe board, for instance, might be as follows:
xox oxo ox xo oxo xoxImplement and test a class representing a 19-by-19 game board. Your representation should be a vector of vectors of characters, all initially set to a period ("."). Your class should include three public member functions:
- a constructor, which initializes all the cells to a period.
- void SetCell (int player, int row, int col, char c)
stores the given character argument at board position [row][col], computed from the given player's perspective. For example, on the 3-by-3 board that, viewed from player 0's perspective, containsxox ox. oxochanging board cell [0][2] to 'M' from player 0's perspective would result in the boardxoM ox. oxowhile changing board cell [0][2] to 'M' from player 1's perspective would result in the boardxox ox. MxoThe players are numbered 0 and 1, and the rows and columns of the board are numbered from 0 to 18. You need not error-check the arguments to SetCell and Print.
Your test cases should include calls to SetCell and Print for each of the two players.
Checklist
- Correctly working code.
- Sufficient testing, with output sufficient to verify test correctness:
- tests of SetCell and Print for each player.
- Printed listings of program text, tests, and test results.
- Adherence to CS 9F style standards:
- appropriate use of indenting and white space;
- avoidance of "forbidden C++";
- variable and function names that reflect their use;
- informative comments at the head of each function;
- no routine more than twenty-four lines of code.
- Clean case analysis and simple loop structuring.