IN C++: The text files babynames1880.txt and babynames2014.txt, which are attach
ID: 3732748 • Letter: I
Question
IN C++:
The text files babynames1880.txt and babynames2014.txt, which are attached to this assignment, contain a list of the most popular boy and girl names in the United States for the years 1880 and 2014 as compiled by the Social Security Administration (it’s interesting to see how baby names have changed over the years!). If you want to see how names have evolved in popularity over time, check out http://www.babynamewizard.com/voyager (Links to an external site.)Links to an external site.. You will see that while Emma seems like a timeless female name if you just look at the babynames1880.txt and babynames2014.txt files (3rd in 1880 and 1st in 2014), it in fact fell rapidly in popularity through 1900, reached its nadir in the 1960s, and then started regaining its popularity in the 1980s.
A baby name file is a space-delimited file in which each line consists of a baby name, the name’s gender, and the number of babies given that name in the given birth year. The most popular names are listed first and the least popular names are listed last. For example, the file begins with:
Emma F 20799
Olivia F 19674
Noah M 19144
Sophia F 18490
Liam M 18342
Mason M 17092
Isabella F 16950
…
The first line indicates that Emma was the most popular girl’s name and was the name given to 20,799 babies. The third line indicates that Noah is the most popular boy name and was the name given to 19,144 babies.
In this part, you will write a program that reads names from a baby names file that is formatted as shown above and prints a nicely formatted report with the top n-ranked names and their frequencies. The user will provide 3 command line arguments—1) the name of the baby names file, 2) the number n of top ranked names to print, 3) and the gender as a capital M or F (male or female)—and then your program will print the top n ranked names for that gender. For example, if the user enters babynames2014.txt, 3, and F as the command line arguments, then your program will print the top ranked 3 female names as follows:
3 Most Popular Baby Names
Name Frequency
Emma 20791
Olivia 19674
Sophia 18490
Here are the formatting requirements for the report:
The names are left-justified in a field 10 characters wide.
The frequencies are right-justified in a field 10 characters wide (the length of the string “Frequency”).
Do not put any spaces between the Name and Frequency fields
Programming note: If the user requests a larger number of names than are in the baby names file, stop printing your report after you have exhausted all the names in the file. For example, if there are 10,000 names in the file, and the user asks for 20,000 names, then print 10,000 names and stop.
Here are several important requirements for this part:
You may not assume that the name of the input file is “babynames2014.txt”. We will test your code by providing other files with baby names via the command line.
You will need to convert the command line argument that represents the number of names to print from a string to an integer. You may use the atoi (). function for this.
Check to make sure that the user entered exactly 3 arguments. Print the following two line message if they did not:
After printing the usage message, return 0 from main to exit your program.
Remember that the name of the program is added by the operating system as the first argument (argv[0]) , and that therefore you program will receive a total of 4 arguments. Hence you will check to see if argc is 4, not 3. You MUST check argc before ever using argv!
Make sure that the file can be opened. If not, output an error message to stdout with the file name in order to print the error message and then return 0 from main to exit your program.
Hint: You do NOT need to use arrays for the babynames in Part 1.
Part 2 – producing a more informative report
In this part you are going to modify the report that your program prints so that it splits the baby names by gender. For example, if the user wants the top 5 baby names, your report will now look like:
5 Most Popular Boys and Girls Names
Girls Frequency Boys Frequency
Emma 20799 Noah 19144
Olivia 19674 Liam 18342
Sophia 18490 Mason 17092
Isabella 16950 Jacob 16712
Ava 15586 William 16687
Here are the formatting instructions:
Use the same formatting for the names and frequencies as specified in part A.
Put 4 blank spaces between the column for Girls Frequency and the column for Boys names.
To produce this report, modify your program from part A so that it loads the entire baby names file and splits the names by gender into a girl array and into a boy array. Your program must also read the name frequencies into two more arrays, one for boys and one for girls.
Next, write a function named printTopNames that prints the report. Move your printing code from part A into this function and then modify it. printTopNames must be a void function that takes 7 parameters: the four arrays (pass the girl and boy name arrays and their corresponding frequency arrays by-reference) as well as the number girls and number of boys along with the number of top names to print. Remember to use const if you are not going to change the arrays. Your function will then print the top names report. If the user requests more names than are available, you must stop printing when you exhaust the array. Therefore, the shortest array’s size will be the number of names you print.
As in Part 1 the number of command line arguments provided by the user must exactly match the number that the program expects or you should print an error message. Since gender is no longer a command line argument, change the error message for an incorrect number of command arguments so that it reads:
Part 3 – Output to a File
For this part of the program – instead of putting the output to the stdout the program will output to an output file. To do this you will need to think about the following changes.
The command line arguments will now be inputfile outputfile followed by the number of names to print. You will need to readjust the code to accommodate this. The error messages will be as:
The output file must be opened and closed in the main program and then passed as an additional parameter to the printTopNames function
Explanation / Answer
There are no attachments provided. Hope the code is self explanortory.
Part1.cpp
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <vector>
using namespace std;
int main(int argc, char*argv[]) {
// checking if the number of arguments to be equal to 4
if(argc != 4) {
cout<<"Wrong number of arguments Correct usage: filename #namesToPrint gender ";
exit(0); //exiting by 0 as mentioned in question.
}
ifstream inFile;
inFile.open(argv[1]);
// if file is not present we must show error
if(!inFile) {
cout<<"Error opening file ";
exit(1);
}
int n = atoi(argv[2]);
char* gender = argv[3];
string name,sex;
int cnt;
// width as 10 and left align;
cout.width(10); cout<<left<<"Name";
// width as 10 and right align;
cout.width(10); cout<<right<<"Frequency"<<endl;
//reading till the end of file.
// looking if reading of name is end of file.
// if not then we will read the gender and count.
// else we will come out of loop.
while(inFile >> name && n!=0) {
inFile>>sex;
inFile>>cnt;
if(sex == gender) {
cout.width(10); cout<<left<<name;
cout.width(10); cout<<right<<cnt<<endl;
n--;// we need only n-1 names. hence decreasing
}
}
return 0;
}
Output
$ ./part1 names.txt 3 F
Name Frequency
Emma 20799
Olivia 19674
Sophia 18490
Part2.cpp
#include <iostream>
#include <fstream>
#include <stdlib.h>
#define MAX 10000
using namespace std;
void printTopNames( string girlsNames[MAX],
string boysNames[MAX],
int girlsFreq[MAX],
int boysFreq[MAX],
int nGirls,
int nBoys,
int n) {
// width as 10 and left align;
cout.width(10); cout<<left<<"Name";
// width as 10 and right align;
cout.width(10); cout<<right<<"Frequency";
cout<<" ";
cout.width(10); cout<<left<<"Name";
cout.width(10); cout<<right<<"Frequency"<<endl;
// the exit condition is either the size or n must be 0
// this way even if user enter number greater than the actual entries in
// file we will display all the data present in file.
int i;
for(i = 0;i < nGirls && i<nBoys && n!=0; i++){
cout.width(10); cout<<left<<girlsNames[i];
cout.width(10); cout<<right<<girlsFreq[i];
cout<<" ";
cout.width(10); cout<<left<<boysNames[i];
cout.width(10); cout<<right<<boysFreq[i]<<endl;
n--;// we need only n-1 names. hence decreasing
}
// case in which the number of girls are more than number of boys.
if( n!=0 && i != nGirls) {
while(i < nGirls && n!=0) {
cout.width(10); cout<<left<<girlsNames[i];
cout.width(10); cout<<right<<girlsFreq[i]<<endl;
i++; n--;
}
}
// case in which the number of boys are more than number of girsl.
if( n!=0 && i != nBoys) {
while(i < nBoys && n!=0) {
cout.width(10); cout<<left<<"";// required for indentation.
cout.width(10); cout<<right<<"";
cout<<" ";
cout.width(10); cout<<left<<boysNames[i];
cout.width(10); cout<<right<<boysFreq[i]<<endl;
i++; n--;
}
}
}
int main(int argc, char*argv[]) {
// checking if the number of arguments to be equal to 4
if(argc != 3) {
cout<<"Wrong number of arguments Correct usage: filename #namesToPrint ";
exit(0); //exiting by 0 as mentioned in question.
}
ifstream inFile;
inFile.open(argv[1]);
// if file is not present we must show error
if(!inFile) {
cout<<"Error opening file ";
exit(1);
}
int n = atoi(argv[2]);
string na,g;
int c;
// arrays to store information of names
string girlNames[MAX], boysNames[MAX];
// arrays to store frequency
int girlFreq[MAX], boysFreq[MAX];
// count of number of boys and girls
int nBoys=0, nGirls = 0;
//reading till the end of file.
// looking if reading of name is end of file.
// if not then we will read the gender and count.
// else we will come out of loop.
while(inFile >> na) {
inFile>>g;
inFile>>c;
// creating object and inserting into vector;
if(g == "F") {
girlNames[nGirls] = na;
girlFreq[nGirls++] = c;
}
else {
boysNames[nBoys] = na;
boysFreq[nBoys++] = c;
}
}
//calling function with 7 parameters as stated in question.
printTopNames(girlNames, boysNames, girlFreq, boysFreq,nGirls, nBoys, n);
return 0;
}
Output:
$ ./part2 names.txt 5
Name Frequency Name Frequency
Emma 20799 Noah 19144
Olivia 19674 Liam 18342
Sophia 18490 Mason 17092
Isabella 16950 Jacob 16712
Ava 15586 William 16687
Part3.cpp
#include <iostream>
#include <fstream>
#include <stdlib.h>
#define MAX 10000 // maximum entries in the file could be.
using namespace std;
void printTopNamesToFile( ofstream &outFile, // argument to print output to file
string girlsNames[MAX],
string boysNames[MAX],
int girlsFreq[MAX],
int boysFreq[MAX],
int nGirls,
int nBoys,
int n) {
// width as 10 and left align;
outFile.width(10); outFile<<left<<"Name";
// width as 10 and right align;
outFile.width(10); outFile<<right<<"Frequency";
outFile<<" ";
outFile.width(10); outFile<<left<<"Name";
outFile.width(10); outFile<<right<<"Frequency"<<endl;
// the exit condition is either the size or n must be 0
// this way even if user enter number greater than the actual entries in
// file we will display all the data present in file.
int i;
for(i = 0;i < nGirls && i<nBoys && n!=0; i++){
outFile.width(10); outFile<<left<<girlsNames[i];
outFile.width(10); outFile<<right<<girlsFreq[i];
outFile<<" ";
outFile.width(10); outFile<<left<<boysNames[i];
outFile.width(10); outFile<<right<<boysFreq[i]<<endl;
n--;// we need only n-1 names. hence decreasing
}
// case in which the number of girls are more than number of boys.
if( n!=0 && i != nGirls) {
while(i < nGirls && n!=0) {
outFile.width(10); outFile<<left<<girlsNames[i];
outFile.width(10); outFile<<right<<girlsFreq[i]<<endl;
i++; n--;
}
}
// case in which the number of boys are more than number of girsl.
if( n!=0 && i != nBoys) {
while(i < nBoys && n!=0) {
outFile.width(10); outFile<<left<<"";// required for indentation.
outFile.width(10); outFile<<right<<"";
outFile<<" ";
outFile.width(10); outFile<<left<<boysNames[i];
outFile.width(10); outFile<<right<<boysFreq[i]<<endl;
i++; n--;
}
}
outFile.close(); // closing the file to print the output.
}
int main(int argc, char*argv[]) {
// checking if the number of arguments to be equal to 4
if(argc != 4) {
cout<<"Wrong number of arguments Correct usage: ifilename ofilename #namesToPrint ";
exit(0); //exiting by 0 as mentioned in question.
}
ifstream inFile;
ofstream outFile;
inFile.open(argv[1]);
// if file is not present we must show error
if(!inFile) {
cout<<"Error opening file ";
exit(1);
}
outFile.open(argv[2]);
// if file is not present we must show error
if(!outFile.is_open()) {
cout<<"Error opening file ";
exit(1);
}
int n = atoi(argv[3]);
string na,g;
int c;
// arrays to store information of names
string girlNames[MAX], boysNames[MAX];
// arrays to store frequency
int girlFreq[MAX], boysFreq[MAX];
// count of number of boys and girls
int nBoys=0, nGirls = 0;
//reading till the end of file.
// looking if reading of name is end of file.
// if not then we will read the gender and count.
// else we will come out of loop.
while(inFile >> na) {
inFile>>g;
inFile>>c;
// creating object and inserting into vector;
if(g == "F") {
girlNames[nGirls] = na;
girlFreq[nGirls++] = c;
}
else {
boysNames[nBoys] = na;
boysFreq[nBoys++] = c;
}
}
//calling function with 7 parameters as stated in question.
// passing out stream to the function.
printTopNamesToFile(outFile, girlNames, boysNames, girlFreq, boysFreq,nGirls, nBoys, n);
return 0;
}
: