formatting vector output using iomanip - c++

I'm having some trouble here. I have a file that looks like this (here's a snippet)
Sophia F 22158
Emma F 20791
Isabella F 18931
Jacob M 18899
Mason M 18856
Ethan M 17547
and I want to put each name, and the name's respective number into seperate vectors. For example, I would have 4 vectors:
1 for women's names and 1 for women's numbers, and the same for men's and men's numbers. (so 4 total)
I have this code, which will go through the file and pull out these elements and put them in vectors.
for (int i = 0; i < numTimes; i++) {
getline (inputFile, inputLine);
ss.str(inputLine); //ss is a string stream
ss >> name >> gender >> popularity;
if (gender == 'M') {
mNames[i] = name;
mFrequency[i] = popularity;
} else if (gender == 'F') {
fNames[i] = name;
fFrequency[i] = popularity;
}
ss.clear();
}
and I use this method to print it out:
cout << counter << " Most Popular Baby Names" << endl << endl;
cout << left << setw(15) << "Girls" ;
cout << right << setw(9) << "Frequency" <<" ";
cout << left << setw(15) << "Boys";
cout << right << setw(9) << "Frequency" << endl;
for (int i = 0; i < counter; i ++) {
cout << left << setw(15) << fNames[i] ;
cout << right << setw(9) << fFreq[i] <<" ";
cout << left << setw(15) << mNames[i];
cout << right << setw(9) << mFreq[i] << endl;
{
but then I get this output:
http://i.stack.imgur.com/2x0ta.png
But I would like for it to be like this:
http://i.stack.imgur.com/OSIX9.png
So I'm thinking I either need to go through before I print and remove all the whitespace/0's in these vectors, or I need to check while I'm printing out. Does anyone have any pointers?

Solved, thanks guys.
I used two separate while loops, one for each set of arrays. In between them I reset the ifstream back to the beginning. This way, it goes through until each vector has 5 non-zero elements.

Related

How to match data in the same file using C++

The program doesn't print the report in columns formatted exactly as shown in the sample output. Can anyone help?
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
int main()
{
char user_gender, user_smoker;
string user_eyecolor;
int user_minAge, user_maxAge, user_minHeight, user_maxHeight;
cout << "What is the gender of your ideal match(M, F, N) ? ";
cin >> user_gender;
cout << "What is the minimum age? ";
cin >> user_minAge;
cout << "What is the maximum age? ";
cin >> user_maxAge;
cout << "What is the minimum height (in inches)? ";
cin >> user_minHeight;
cout << "What is the maximum height (in inches)? ";
cin >> user_maxHeight;
cout << "Smoker (Y/N)? ";
cin >> user_smoker;
cout << "What is the eyecolor (Blue, Green, Grey, Brown)? ";
cin >> user_eyecolor;
cout << endl << endl;
//Variables to check against the conditions
int countGender = 0;
int partialMatch = 0;
int fullMatch = 0;
cout << endl << left << setw(1) << " Name" << fixed << right << setw(22) << "Age" << fixed << right << setw(12) << "Height" << fixed << right << setw(12) << "Smoker" << fixed << right << setw(15) << "Eye Color" << fixed << right << setw(22) << "Phone" << endl;
cout << "-----------------------------------------------------------------------------------------------------------------" << endl;
//Now read the file data.
ifstream fin("matches.txt");
if (fin.is_open())
{
while (!fin.eof())
{
string firstname, lastname, eyecolor, phoneno;
char gender, smoker;
int age, height;
fin >> firstname >> lastname >> gender >> age >> height >> smoker >> eyecolor >> phoneno;
if (gender == user_gender)
{
countGender++;
//Now check to see if the age and height are between the maximum and minum preferences.
if ((age >= user_minAge && age <= user_maxAge) && (height >= user_minHeight && height <= user_maxHeight))
{
//Then check to see if the smoking preference and eye color are also a match.
if (user_smoker == smoker && user_eyecolor == eyecolor)
{
fullMatch++;
cout << "* " << firstname << " " << lastname << setw(25) << age << setw(11) << height << setw(11) << smoker << setw(11) << eyecolor << setw(11) << phoneno << endl;
}
else if (eyecolor == user_eyecolor)
{
partialMatch++;
cout << " " << firstname << " " << lastname << setw(24) << age << setw(11) << height << setw(11) << smoker << setw(11) << eyecolor<< setw(11) << phoneno << endl;
}
}
}
}
cout << "-----------------------------------------------------------------------------" << endl;
cout << "There were " << fullMatch << " matches and " << partialMatch << " partial matches out of " << countGender << " records." << endl;
cout << "-----------------------------------------------------------------------------" << endl;
fin.close();
}
else {
cout << "File did not open";
}
return 0;
}
****The program is working perfectly fine, but I am not getting the output printed in columns formatted as shown in the above sample output. ****
Write a program that opens the file and reads the records one by one. The program will skip any records where the gender preference is not a match. Of those records that match the gender preference, check to see if the age and height are between the maximum and minimum preferences. Then check to see if the smoking preference and eye color are also a match. If at least 3 of the remaining fields match, consider the record a partial match, and print it in the report. If all 4 of the remaining fields match, the record is a perfect match and print it in the report with an asterisk next to it. At the end of the program, close the file and report how many total records there were of the specified gender, how many were a partial match, and how many were a perfect match.
Charlie Bradbury F 42 65 N Green 555-867-5309
Bobby Singer M 70 69 Y Brown 555-867-5309
Dean Winchester M 43 72 N Brown 555-867-5309
Sam Winchester M 39 75 N Brown 555-867-5309
Bela Talbot F 39 69 Y Blue 555-867-5309
James Novak M 46 71 Y Blue 555-867-5309
Use a proper IDE with debugging capabilities (e.g. Visual Studio Community Edition).
Set a breakpoint at the first line of the method which is problematic, e.g. line 9 in your case
Step over your code line by line and see what it does.
Hover over variables or use the locals or watch window to see the values of variables
Think about what you expected to see and compare it to what you actually see. In 99% of the cases, the computer is more right than you and it's a misunderstanding on your side.

Input for one line is messing up, code is similar all throughout

Hello this program i made is supposed to obtain a height in inches (age 1-18) from the user and based off the amount, produce the an estimated height when the individual becomes an adult. The program works as inteded except when I input womens height it does not come out properly. It shows up as the numbers 1-18, compared to the mens height which shows whatever was input. This issue also messes up the equation because instead of calculating using the input number it uses 1-18. I get the error
Warning C6385 Reading invalid data from 'growthChart[x]': the readable size is '40' bytes, but '48' bytes may be read.
but it only shows under the line cin >> growthChart[x][5];. Not sure how i should go about fixing this becuase i see no issue with it and the other similar problems I looked up were in different cases.
int main()
{
double growthChart[19][5] = { {0,28.6,30.9},{1,42.2,44.7},{2,49.5,52.8},{3,53.8,57},{4,58,61.8}, {5,61.8,66.2},{6,65.2,70.3},
{7,69,74},{8,72,77.5},{9,75,80.7},{10,78,84.4},{11,81.1,88.4},{12,84.2,92.9},{13,87.3,96.5}, {14,91.5,98.3},
{15,96.1,99.1},{16,98.3,99.6},{17,99.3,100},{18,99.8,100} };
char choice;
bool runAgain = true;
int x;
while (runAgain)
{
for (x = 0; x < 19; x++)
{
cout << "\nAge in Years " << x;
growthChart[x][0] = x;
cout << "\nEnter Boys height in inches:: ";
cin >> growthChart[x][4];
cout << "\nEnter Girls height in inches :: ";
cin >> growthChart[x][5];
}
cout << "\n\n" << "The displayed height shows feet as a whole number and the decimal as inches.";
cout << "\n\n" << setw(10) << "Age" << setw(25) << "Boys height(inches)" << setw(25)<< "Growth percentage" << setw(25) << "Boys height(feet/inches)"
<< setw(25) << "Girls height(inches)" << setw(25) << "Growth percentage" << setw(25) << "Girls height(feet/inches)";
for (x = 0; x < 19; x++)
{
cout << "\n" << setw(10) << growthChart[x][0] << setw(25) << growthChart[x][4] << setw(25) << growthChart[x][1]<< "%" << setw(25) << ((growthChart[x][4]*(100 / growthChart[x] [1]))/12)
<< setw(25) << growthChart[x][5] << setw(25) << growthChart[x][2] << "%" << setw(25) << ((growthChart[x][5]*(100 / growthChart[x][2]))/12);
}

I am trying to polish my output using (setw) but if the value that i enter differ in range it does not work properly

I am trying to fix my output using setw(4).I have tried different a range of number between 1 to 10 but none get me the desired output.
void Students(int& size_public)
{
cout << "Input the number of information to be entered: ";
cin >> size_public;
cout << endl << endl;
// Reseting the screen
system("cls");
for (int i = 0; i < size_public; i++)
{
cout << "________________________Enter the following information for the data to be stored________________________\n" << endl;
cout << "Name: ";
cin >> employees[i].name_public;
cout << "Age: ";
cin >> employees[i].age_public;
cout << "ID.No: ";
cin >> employees[i].ID_No_publice;
cout << endl;
system("cls");
}
}
void Students(Employee employees[arraysize], int& size_public)
{
for (int i = 0; i < size_public; i++)
{
if (i == 0)
{
cout << setw(10) << "Name\t" << "Age\t" << "ID.No" << endl << endl;
}
cout << setw(10) << employees[i].name_public << '\t'
<< employees[i].age_public << '\t'
<< employees[i].ID_No_publice << endl;
}
}
};
Later in the program it is called
if (selection == 2)
{
student.Students(size);
cout << "1. Leave\n";
cout << "2. Showinformation\n";
cout << "\n________________________________________________\n";
cout << "Enter your choice: ";
cin >> choice;
cout << "\n________________________________________________\n";
if (choice == 1)
{
cout << endl;
}
else if (choice == 2)
{
student.Students(student.employees, size);
}
else if (choice != 1 && choice != 2)
{
cout << "choice is not found\n";
}
}
This is what I am talking about
Name Age ID.No
fge 33 345674
sdfgfd 34 23
dfghjkjhg 354 54345
Space behind the names is what I am trying to avoid
This is the output i receive when i use setw(10)
and this is what happen when the range of input changes
Name Age ID.No
afjghbslkk;jfl 2 3
fg 3 5.67654e+06
3 34543 543
if you look at fg in name it has a space behind it and I am trying to avoid it
My desired output is something like
Name age ID.No
dfghsgffgdf 44553 4564564
ajkghjkgh 444 465454
ff 4 46
I do not know if it is possible but if I am missing any thing just let me know and i will update the code.
Example
if (i == 0)
cout << left << setw(10) << "Name" << setw(10) << "Age" << setw(10) << "ID.No" << endl << endl;
cout << left << setw(10) << employees[i].name_public
<< setw(10) << employees[i].age_public
<< setw(10) << employees[i].ID_No_publice << endl;
See if this is what you need.

Different Outputs of an Atoi Converted String-> int

Here is my input file:
Plain Egg
1.45
Bacon and Egg
2.45
Muffin
0.99
French Toast
1.99
Fruit Basket
2.49
Cereal
0.69
Coffee
0.50
Tea
0.75
This is my code. I'm having no problem when people order 8 or 9 items, but as soon as they enter 10 or more items, I get really weird results and not the nicely printed check that I would like to see. For instance, let's say someone orders 8 items and they input "12345678" for their order. I get this:
But if the user inputs that they want let's say 15 items and they order "123456781234567", I get THIS:
Even when they order 10 items, I get just a blank check :/ :
What in the world is happening with my program? Does it have to do with me using c-strings? I want to understand what is going on inside my little computer and understand the way my computer thinks. If you can explain me this in a very simple way (I'm really new so I need something very explanatory with definitions of your fancy words) and some way I can understand, because like I said, I'm really new to computer science. Thank you.
// Local Restaurant: The 5,000 Fed
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
struct menuItemType {
string menuItem;
double menuPrice;
};
void getData(menuItemType list[]);
string showMenu(menuItemType list[]);
void printCheck(string y, menuItemType list[]);
int main() {
string y;
menuItemType menuList[8];
cout << "Hello and welcome to the 5,000 fed. Your local Long Beach café, "
"whose name is inspired by Jesus' miraculous manifestation "
"of bread to feed the 5k! His disciples helped him in passing out "
"the bread, and so I am here, your waiter, to help you and assist "
"you with your order. ";
getData(menuList);
y = showMenu(menuList);
printCheck(y, menuList);
return 0;
}
void getData(menuItemType list[]) {
string menupricet[8];
ifstream inFile;
inFile.open("menudata.txt");
for (int i = 0; i < 8; i++) {
getline(inFile, list[i].menuItem);
getline(inFile, menupricet[i]);
}
for (int i = 0; i < 8; i++) {
list[i].menuPrice = atof(menupricet[i].c_str());
}
}
string showMenu(menuItemType list[]) {
int amount;
char number;
string reps;
string response = "y";
string total = "";
cout << fixed << setprecision(2);
cout << endl << endl;
cout << "Here is our wonderful menu. I do recommend the french toast, "
"similar to the bread that Jesus ate."
<< endl
<< endl;
for (int i = 0; i < 8; i++) {
cout << i + 1 << ". " << setw(13) << left << list[i].menuItem << setw(8)
<< right << list[i].menuPrice << endl;
}
cout << endl;
cout << "How to order: Write the number you would like and specify how many "
"you want of that item by typing it in multiple times. For instance "
"an input of \"1135777\" means that you want two plain eggs, one "
"muffin, one fruit basket, and three coffees."
<< endl
<< endl;
cout << "How many items are you ordering total?: ";
cin >> amount;
cout << endl;
cout << "Please input your order, and press enter after your order: ";
for (int i = 0; i < amount; i++) {
cin >> number;
total += number;
}
return total;
}
void printCheck(string y, menuItemType list[]) {
int k = 0;
int temp = 0;
double bill = 0;
int newone = 0;
k = atoi(y.c_str());
while (k != 0) {
newone = newone * 10;
newone = newone + k % 10;
k = k / 10;
}
cout << "Thank you for dining at the 5,000 fed. Here's your check:" << endl
<< endl
<< endl;
cout << "_________________" << endl;
while (newone > 0) {
temp = newone % 10;
newone /= 10;
bill += list[temp - 1].menuPrice;
cout << left << setw(15) << list[temp - 1].menuItem << right << setw(5)
<< "|" << list[temp - 1].menuPrice << endl;
}
cout << fixed << setprecision(2);
cout << left << setw(15) << "Amount Due:" << right << setw(10) << "|" << bill
<< endl
<< endl;
}
EDIT:
So someone asked me to paste the output as text instead of images so here are the three outputs:
They order 8 items such as "12345678":
_________________
Plain Egg |1.45
Bacon and Egg |2.45
Muffin |0.99
French Toast |1.99
Fruit Basket |2.49
Cereal |0.69
Coffee |0.50
Tea |0.75
Amount Due: |11.31
They order 15 items such as "123456781234567":
_________________
French Toast |1.99
\365\277\357\376^ޝ-
YW\300\365\277\357\376all\377
\200\367\277\357\376
\370\277\357\376
\227\370\277\357\376
\331\370\277\357\376%\371\277\357\376\262
|0.00
Coffee |0.50
Muffin |0.99
\362\277\357\376x\362\277\357\376x\362\277\357\376x\362\277\357\376Plain Egg33333 |0.00
Plain Egg |1.45
Cereal |0.69
\365\277\357\376^ޝ-YW\300\365\277\357\376all\377\200\367\277\357\376\370\277\357\376\227\370\277\357\376\331\370\277\357\376%\371\277\357\376\262 |0.00
Cereal |0.69
Amount Due: |6.31
They order 10 items such as "1234567812":
_________________
Amount Due: |0.00
The problem in your code is associated with the size of the type int. Here is the solution, you may declare k and new one as unsigned long int so that they can hold up to 4,294,967,295 which still contains only 10 orders.
As a solution, you can use the string y as it is instead of converting to int. So that you can place as many orders as you wish. To traverse through the orders, you can use substr and length function of the string.
Let me re-write the printCheck function for, if I may
void printCheck(string y, menuItemType list[]) {
double bill = 0;
for(int i = 0; i< y.length(); i++)
{
string a = y.substr(i, 1);
int kk = atoi(a.c_str());
bill += list[kk - 1].menuPrice;
cout << left << setw(15) << list[kk - 1].menuItem << right << setw(5)
<< "|" << list[kk - 1].menuPrice << endl;
}
cout << fixed << setprecision(2);
cout << left << setw(15) << "Amount Due:" << right << setw(10) << "|" << bill << endl;
}
I hop this helps. Regards.

Display data in two columns c++

I am trying to display the same data but in two columns, so after school week 19, the data should be displayed in the columns to the right of the table until the total school weeks is reached i.e. 36. Below is the code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int const schoolWeeks = 37;
string week[] = { "A", "B", "C", "D" };
int num = 0;
int main()
{
cout << left << setw(9) << setfill(' ') << "Week " << left << setw(9) << setfill(' ')<< "Menu" << left << setw(9) << setfill(' ') << "Week " << "Menu" << endl;
for (int i = 1; i < 20; i++)
{
cout << left << setw(9) << setfill(' ')<< i << week[num] << endl;
num = num + 1;
if (num == 4)
{
num = 0;
}
}
for (int i = 20; i < schoolWeeks; i++)
{
cout << left << setw(9) << setfill(' ') << i << week[num] << endl;
num = num + 1;
if (num == 4)
{
num = 0;
}
}
}
Standard output with std::cout is based on the idea of a stream of data. Remember, it's called "iostream" for a reason. This means once you have written something to std::cout, you simply cannot "go back" a few lines and add something.
Consider piping in a Linux shell or on the Windows command line. It's possible to redirect the output of your program to be the input of another program, which could then do any imaginable thing with it, e.g. sending it over the internet:
myprogram.exe > otherprogram.exe
How could you possibly add something to an already written line in such a scenario?
Considering all of this, it becomes clear that the only viable solution is to know in advance the contents of every line. You cannot wait until line 19 before thinking about the second column, you must do it right away. In other words, first print week 1 and week 19, then week 2 and week 20, then week 3 and week 21, and so on. See the pattern? It's always "week X in column one, week X+18 in column two". And that's pretty much the solution.
Here's a quickly written loop adhering to the style of your existing code:
for (int i = 1; i < 19; i++)
{
cout << left << setw(9) << setfill(' ')<< i << week[num]
<< left << setw(9) << setfill(' ') << " " << (i + 18) << " "
<< left << setw(9) << setfill(' ') << " " << week[num]
<< endl;
num = num + 1;
if (num == 4)
{
num = 0;
}
}
The manipulators like std::setw or std::setfill could probably use some improvement, but the point is that:
The loop only counts from 1 to 18.
The body performs the output for i and for i + 18.