CS 311 Fall 2020 > Project 8
CS 311 Fall 2020
Project 8
Project 8 is due at 5 pm Tuesday, December 1. It is worth 60 points.
Procedures
This is, optionally, a group assignment. You may work in a group of 2 or 3, if you wish. Each group only needs to turn in a single copy of the assignment. Under normal circumstances, each group member will receive the same grade on the assignment.
Turn in answers to the exercises below on the UA Blackboard Learn site, under Project 8 for this class.
- Your answers should consist of two files:
countwords.cpp
, from Exercise A, andsquarer_test.cpp
, from Exercise B. - I may not look at your homework submission immediately. If you have questions, e-mail me.
If you work in a group:
- The project files should contain the names of all group members.
- One student should submit the project as usual, on Blackboard.
- The other student(s) should submit an empty project (no attached files) on Blackboard, with a note in the comments box indicating whom the project was done with.
Exercises (60 pts total)
Exercise A — Program: Counting Words
Purpose
In this exercise, you will write a program that uses a C++ STL Table implementation. Your program will also read information from a file. Robustness and proper error checking are an important part of the assignment.
Background
For the purposes of this exercise, a word is a contiguous sequence of one or more non-space characters.
For example, consider the following.
xyz/ xyz123 xyz xyz123 xyz abc
The words in the above text, in lexicographic order, are
abc
, xyz
, xyz/
,
and xyz123
.
Instructions
Write a complete C++ program (including function main
!)
that inputs a filename from the user,
and reads the named file.
The program should then print
the number of distinct words that appear in the file,
followed by a list giving, for each word appearing,
the word itself and the number of times it appears in the file,
as shown below.
Be sure to follow the
coding standards.
All standards now apply!
- Store the source for your program in a single file:
countwords.cpp
. - Your program must store its results, prior to printing, in an appropriate STL Table container.
- See the Testing section, below, for an example of the kind of output I am looking for.
- Your program should be robust. That is, it should never crash, no matter what the user types, and no matter what it finds in the file.
Testing
Since you are writing a complete program this time,
there will be no test program.
However, I have created a test input file:
countwords_test.txt
.
(This file is also in the Git repository.)
If you run your program with this file as input,
then it should output the following
statistics.
Number of distinct words: 45 2020: 1 2020-11-20: 1 311: 1 8,: 1 A: 1 And: 1 CS: 1 Can: 2 Chappell: 1 Exercise: 1 Fall: 1 For: 1 G.: 1 Glenn: 1 Next: 1 Project: 1 Test: 1 What: 1 a: 3 again.: 1 change: 2 correctly: 2 count: 2 countwords_test.txt: 1 ending: 1 file: 2 for: 1 if: 1 input: 1 is: 2 it: 1 line-ending: 1 line.: 1 line?: 1 long: 2 marker?: 1 newline?: 1 no: 1 the: 1 there: 1 we: 2 when: 1 with: 1 word: 100000 you: 2
Do not turn in countwords_test.txt
.
Note that I may test your program using a different input file.
Hints
Using “
cin >> ...
” is almost never appropriate when reading from the user, because this reads individual words while the user thinks in terms of lines. Instead, usestd::getline
to grab a whole line at a time.- To check for errors when using C++ streams,
first use the “
!
” operator on the stream; then use member functioneof
.For example, if you have an
ifstream
calledinfile
, then after every operation oninfile
, you should do
This is a check for an error on the last operation. If this test succeeds (that is, if there was an error), and the operation was a read, then check for EOF next:if (!infile) { ...
if (infile.eof()) { ...
If this is true, then the error was due to the end of the file, and so there is nothing wrong with the file; just stop reading. On the other hand, if you get an error that is not due to EOF, then there is something wrong with the file (or the device, or the connection with the device, or ...).
- Robustness means that the user is allowed to do strange things,
and files are allowed to contain strange data,
but the program never behaves badly.
Test the strange cases. For example, what if the user, when prompted for a filename, just hits ENTER? What if they type a bunch of blanks and then hit ENTER? What about a filename with a blank in the middle? What about the name of a file that does not exist? A file that exists but cannot be read? An empty file? An executable file? a directory? Etc.
Exercise B — Writing a Test Suite
Purpose
In this exercise, you will write a test suite for a simple C++ class. You will use the doctest testing framework.
Background
Consider a class Squarer
.
Objects of this class are function objects
that compute the square of a numeric argument.
An object of type Squarer
might be used as follows.
[C++]
Squarer sq; int n = sq(5); // Computes 5 squared: 125 int d = sq(1.1); // Computes 1.1 squared: 1.331
Here is a complete, correct definition
of class Squarer
:
[C++]
// class Squarer // Class invariants: None. class Squarer { public: // operator() // Returns square of its parameter. // Requirements on types: // Num must have op*, copy ctor. // Throws what & when Num operations throw. // Strong guarantee // Exception neutral template<typename Num> Num operator()(const Num & k) const { return k * k; } // Default ctor, copy ctor, move ctor, copy =, move =, dctor: // automatically generated versions used. };
Instructions
Modify the posted file squarer_test.cpp
so that it
along with doctest.h
,
forms a thorough test program
for class Squarer
,
contained in header file "squarer.h"
.
- Your tests must use the doctest testing framework.
- Each
REQUIRE
directive (or other similar directive:REQUIRE_FALSE
, etc.) must have one or more associatedINFO
directives that give the user information for each failing test. - Your test suite must address all of the following
issues.
- Do both const & non-const
Squarer
objects work? - Does
Squarer
work properly for a wide range of values? - Does
Squarer
work properly for both positive and negative values? - Does
Squarer
work properly for both integer and floating-point arguments? - Special cases of interest: the squares of
0
,1
, and-1
should be correct. - When a test fails, is the message printed both correct and helpful?
- Do both const & non-const
- The compilation requirement in the coding standards,
as applied to this exercise,
means that your code must compile with a correct
version of
"squarer.h"
.
Do not turn in file doctest.h
.
Hints
- For the basics of writing a test suite using doctest, see the slides from November 20.
- Write both correct and incorrect versions of
file
"squarer.h"
, and try out your test program with these.