So our objective here is this:
Requirements.
Write a program named nameSorter.cpp, to read names in a text file, sort them alphabetically, and print them to the screen. Here are some detailed specifications:
The names are to be stored in a text file, one name per line. Prompt the user to enter the filename via the keyboard (ref. section 5.2.3).
Skip any blank lines (ref. section 3.3.3 for string length). Skip any exact duplicates (ref. section 6.1 for text comparison, and 12.1.2's "Two Boolean Search Loops For A List"). Allow up to 8 names (ref. section 12.1).
Stop reading the file after the end-of-file is reached (ref. section 7.3.2), or the 8th name is read (ref. section 7.4).
Sort the names alphabetically, from A to Z (ref. section 10.2.3), however they appear in the file. For example, "Abraham" comes before "George". Or if the names are in the format first-last, "Abraham Lincoln" comes before "George Washington". Or if the names are in the format last-name-first, "Jefferson, Thomas" comes before "Madison, James". (In fact, the text does not even need to be names!)
The sorting and checking for duplicates should both be case-independent (ref. section 6.4.1). But do not permanently convert the name case -- compare lowercase (or uppercase) versions of the text for sorting purposes. (You may want to use temporary variables so store the converted text.)
Write your own input file for testing purposes. Do not submit your input file.
Be sure to use the code from chapter 12 for adding values to a list, and not the code from chapter 10. This means that the size counter should start a zero, and be incremented by one every time a value gets added. The purpose is to show the difference between arrays and lists.
Scoring. The lab will be returned for redo if you do not apply array-based list concepts. The lab will be returned for redo for using a capacity other than 8. The lab will be returned for redo for not checking for duplicates, or for not doing a case-independent check for duplicates. The lab will be returned for redo for permanently converting the case of input values, not skipping blank lines in the input file, or not doing a case-independent sort.
So I completed the assignment as so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
#include <cctype>
class toUpper {public: char operator()(char c) const {return toupper(c);}};
int main()
{
cout << "Editor(s) used: XP Notepad" << endl;
cout << "Compiler(s) used: VC++ 2010 Express" << endl;
cout << "Description: This program alphabetically sorts the first 8 names" << endl;
cout << " from a user-specific text file." <<endl;
cout << endl;
string filename;
string line;
string nameX;
string nameY;
string swap;
int count = 0;
bool nameTaken = false;
ifstream fin;
const int MAX_NAMES = 8;
int SIZE = 0;
string name[MAX_NAMES];
while (1)
{
cout << "Enter filename: ";
getline(cin, filename);
if (filename.length() > 0) break;
cout << "Enter filename: " << endl;
}
cout << endl;
// open and read input file
fin.open(filename.c_str());
if (!fin.good()) throw "I/O error";
while (fin.good() && SIZE < 10)
{
getline(fin, line);
if (line.length() == 0) continue;
nameTaken = false;
for (int i = 0; i < SIZE; i++)
if (name[i] == line)
nameTaken = true;
if (!nameTaken && SIZE < MAX_NAMES)
{
name[SIZE++] = line;
}
}
// sort names
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
nameX = name[i];
nameY = name[j];
transform(nameX.begin(), nameX.end(), nameX.begin(), toUpper());
transform(nameY.begin(), nameY.end(), nameY.begin(), toUpper());
if (nameX < nameY)
{
swap = name[i];
name[i] = name[j];
name[j] = swap;
}
}
}
for (int i = 0; i < SIZE; i++)
cout << name[i] << endl;
return 0;
}
|
I got this for feedback:
"LAb12d: your program must skip any exact duplicates. Note, the checking for duplicates should be case-independent (ref. section 6.4.1).(-2) Pls fix and resubmit."
Okay, so I wrote this (it compiles, but crashes when you load the input txt file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
#include <cctype>
class toUpper {public: char operator()(char c) const {return toupper(c);}};
int main()
{
cout << "Editor(s) used: XP Notepad" << endl;
cout << "Compiler(s) used: VC++ 2010 Express" << endl;
cout << "Description: This program alphabetically sorts the first 8 names" << endl;
cout << " from a user-specific text file." <<endl;
cout << endl;
string filename;
string line;
string nameX;
string nameY;
string swap;
int count = 0;
bool nameTaken = false;
ifstream fin;
const int MAX_NAMES = 8;
int SIZE = 0;
string name[MAX_NAMES];
string nameCopyA;
string nameCopyB;
while (true)
{
cout << "Enter filename: ";
getline(cin, filename);
if (filename.length() > 0) break;
cout << "Enter filename: " << endl;
}
cout << endl;
// open and read input file
fin.open(filename.c_str());
if (!fin.good()) throw "I/O error";
while (fin.good() && SIZE < 10)
{
getline(fin, line);
if (line.length() == 0) continue;
nameCopyA = line;
transform(nameCopyA.begin(), nameCopyA.end(), nameCopyA.begin(), toUpper());
nameTaken = false;
for (int i = 0; i < SIZE; i++)
nameCopyB = name[SIZE];
transform(nameCopyB.begin(), nameCopyB.end(), nameCopyB.begin(), toUpper());
if (nameCopyA == nameCopyB)
nameTaken = true;
if (!nameTaken && SIZE < MAX_NAMES)
{
name[SIZE++] = line;
}
}
// sort names
for (int i = 0; i < SIZE; i++)
{
for (int j = 0; j < SIZE; j++)
{
nameX = name[i];
nameY = name[j];
transform(nameX.begin(), nameX.end(), nameX.begin(), toUpper());
transform(nameY.begin(), nameY.end(), nameY.begin(), toUpper());
if (nameX < nameY)
{
swap = name[i];
name[i] = name[j];
name[j] = swap;
}
}
}
for (int i = 0; i < SIZE; i++)
cout << name[i] << endl;
return 0;
}
|
The txt file is simple. Call it test.txt. Here is the contents of test:
George Washington
John Adams
Thomas Jefferson
james Madison
James Madison
James Monroe
john Quincy Adams
Andrew Jackson
Martin Van Buren
William Harrison
John Tyler
James Polk
Zachary Taylor
Millard Fillmore
Franklin Pierce
James Buchanan
Abraham Lincoln
Andrew Johnson
Ulysses Grant
It should skip the duplicated entry for James Madison given the case sensitivity, and only print the first eight. I know this is a long post, but I'm not asking anyone to do my homework for me, just looking for help on debugging what I have already spent my time on. What gives???