How could I improve this c++ program without vectors? - c++

**Guidelines:**get 3 seperate lists of data(array) for head of household, annual income, and household members, then get all annual incomes and average them together. Display in a neat table.
This is from a school project I wasn't allowed to use anything very advanced but I'd like to go back and improve it now. I'd like ti make it cleaner and particularly like to find more that I can take away from it than add to it.
// <Program Name> Programming Project #3 Average Income (Using Functions and Arrays)
// <Author> Brendan Jackson
// <Date of Programs Release> 08/05/15
// <Program Description> takes 3 arrays and displays them with average income
#include <iostream> // allows cin and cout statements
#include <iomanip> //allows setprecision
#include <string> //allows strings
using namespace std; // Namespace std allows program to use entities from <iostream>
int input(string[], int[], double[]); //function 1
double calculate_average_income(double[], int); //function 2
void display_survey_data(string[], int[], double[],int , double); //function 3
int main() // main function
{
//variables for functions
string name[10];
int members[10];
double income[10];
int count_of_households;
double average;
//get input
count_of_households = input(name, members, income);
//calculate average
average = calculate_average_income(income, count_of_households);
//output all data in table
display_survey_data(name, members, income, count_of_households, average);
return 0;
}
int input(string name[], int members[], double income[]) //function 1
{
// get household info
int count_of_households = 0;
cout << "How many house holds were there? ";
cin >> count_of_households;
//TODO: handle bad input (characters and decimals)
if (count_of_households >= 11 || count_of_households < 0)
{
cout << "must enter valid # " ; //TODO: more description
count_of_households = 0; //set back to safe value
}
else
{
//cycle through arrays
for (int count = 0; count < count_of_households; count++) //TODO: take out (count + 1) start from 1 alternatively
{
// get survey info for names
cout << "Enter household #" << (count + 1) << "'s head of household name\t" ;
cin.ignore() ; // ignores keyboard buffer characters
getline (cin, name[count]) ;
// get survey info for income
cout << "Enter household #" << (count + 1) << "'s annual income\t" ;
cin >> income[count];
// get survey info for members
cout << "Enter household #" << (count + 1) << "'s household members\t" ;
cin >> members[count];
}
}
return count_of_households;
}
double calculate_average_income(double income[], int count_of_households) //function 2
{
//add incomes together
double total = 0.0;
double average = 0.0;
//loop over income
for (int count = 0 ; count < count_of_households; count++)
{
//add income to runnning total
total += income[count];
}
// save calculations
average = total / count_of_households;
return average;
}
void display_survey_data(string name[], int members[], double income[],int count_of_households, double average) //funtion 3
{
//print out header
cout << setw(30) << ""
<< setw(30) << ""
<< setw(30) << "NUMBER OF\n" ;
cout << setw(30) << "HOUSEHOLD NAME"
<< setw(30) << "ANNUAL INCOME"
<< setw(30) << "HOUSEHOLD MEMBERS\n" ;
cout << setw(30) << "--------------------"
<< setw(30) << "---------------"
<< setw(30) << "------------------------\n" ;
///loop over values
for (int count = 0 ; count < count_of_households; count++)
{
cout << setw(30) << name[count]
<< setw(30) << setprecision(2) << fixed << showpoint << income[count]
<< setw(30) << members[count]
<< endl;
}
// display average
cout << endl
<< setw(30) << "AVERAGE INCOME"
<< setw(30) << average
<< endl;
}

You could use std::array
This is simply an array on the stack, just like you used, but has iterators, type safe, bound safe, use value semantics and work with most stl algorithm.
It is declared like this:
array<string, 3> myArray;
And it must be passed by reference, because passing by value will copy it's content:
void doSomething(array<int, 6>& aArray) {
// do something
}
Notice that you must specify the length of the array, since it's a template parameter. If you want to have an array of any size, use tempaltes:
template<size_t length>
void foobar(array<double, length> theArray) {
// do something else
}

Related

How to keep decimal value when getting data from a text file?

I have a text file with info like this (there are 127 lines, I'll provide a few too keep it short):
Gibraltar 133.25
Israel 104.81
Seychelles 85.89
United-Arab-Emirates 63.95
Falkland-Islands 49.73
My program does work in printing country name and number with the most vaccinations, however it just prints a whole number with no decimals. This is especially problematic with lowest since theres multiple countries with numbers between 0 and 1, and it just prints the first 0 down the list, so not the true minimum, here is my code:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
void file(string country[], double vaccinations[]);
void highest(string country[], double vaccinations[]);
void lowest(string country[], double vaccinations[]);
void average (string country[], double vaccinations[]);
void welcomeMessage();
int main() {
//declare variables and arrays, set vaccinations and countries arrays to 127 for the number of countries, amd subsequent vaccination data
string countries[127];
double vaccinations[127];
file(countries, vaccinations);
//call wecome message function
welcomeMessage();
//calls function to count highest vaccination rate and country names
highest(countries, vaccinations);
cout << endl;
//calls function to count lowest vaccination rate and country name
lowest(countries, vaccinations);
//calls function to print the average vaccination rate
//average(countries, vaccinations);
}
void welcomeMessage() {
cout << "Welcome to the vaccine data analysis program!" << endl;
cout << endl;
cout << "This program will print which country currently has admistered the most COVID-19 vaccine doses per 100 people" << endl;
cout << endl;
cout << "The program will also print which country currently has administered the least, per 100 people, as well as the average dose administration per 100 people, out of 127 countries on the list." << endl;
cout << endl;
}
void file(string country[], double vaccinations[]) {
int index = 0;
ifstream inFile;
inFile.open("vaccinations.txt");
if (!inFile.is_open()) {
cout << "Unable to open file." << endl;
} else {
while (index < 127) {
//add code to isolate country string
inFile >> country[index];
//add code to isolate vaccination percentage
inFile >> vaccinations[index];
index++;
}
}
}
void highest(string country[], double vaccinations[]) {
string highestCountry = country[0];
int highestTotal = vaccinations[0];
for (int i = 1; i < 127; i++) {
if (vaccinations[i] > highestTotal) {
highestTotal = vaccinations[i];
highestCountry = country[i];
}
}
cout << highestCountry << " has the highest number of vaccinations at " << fixed << setprecision(100) << highestTotal << " per 100 people." << endl;
}
void lowest(string country[], double vaccinations[]) {
string lowestCountry = country[0];
int lowestTotal = vaccinations[0];
for (int i = 1; i < 127; i++) {
if (vaccinations[i] < lowestTotal) {
lowestTotal = vaccinations[i];
lowestCountry = country[i];
}
}
cout << lowestCountry << " has the lowest number of vaccinations at " << fixed << setprecision(100)<< lowestTotal << " per 100 people." << endl;
}
You declared
int highestTotal = vaccinations[0];
therefore, it drops decimals when you copy floating point values into it.
Declaring highestTotal and lowestTotal as doubles should help:
double highestTotal = vaccinations[0];
and
double lowestTotal = vaccinations[0];
EDIT: as #Casey suggests, we can slightly rewrite it (you can add the welcome message and file correctness check if you wish);
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
struct Country {
string name;
double rate;
};
istream& operator>>(std::istream& in, Country& country) {
return in >> country.name >> country.rate;
}
int main()
{
ifstream inFile;
inFile.open("vaccinations.txt");
auto comparator = [](const Country& x, const Country& y) { return x.rate < y.rate; };
auto [min, max] = minmax_element(istream_iterator<Country>{inFile}, istream_iterator<Country>{}, comparator);
string highestCountry = max->name;
double highestTotal = max->rate;
cout << highestCountry << " has the highest number of vaccinations at " << highestTotal << " per 100 people." << endl << endl;
string lowestCountry = min->name;
double lowestTotal = min->rate;
cout << lowestCountry << " has the lowest number of vaccinations at " << lowestTotal << " per 100 people." << endl;
}

How would I calcuate the total of all the items entered to then calculate the total price?

Hi there apologise if my question is poorly worded, I'm struggling to find a solution to my problem.
The purpose of my program is to allow the user to enter predefined bar codes that associate with items and a price. The user enters as many barcodes as they want, and when they're done they can exit the loop by pressing "F" and then total price for all the items is displayed.
This is my code so far, I'm very new to programming..
#include <iostream>
#include <iomanip>
using namespace std;
int index_of(int arr[], int item, int n) {
int i = 0;
while (i < n) {
if(arr[i] == item) {
return i;
}
i++;
}
return -1;
}
const int SIZE = 10;
int main()
{
string item [SIZE] = {"Milk", "Bread", "Chocolate", "Towel", "Toothpaste", "Soap", "Pen", "Biscuits", "Lamp", "Battery"};
int barcode [SIZE] = {120001, 120002, 120003, 120004, 120005, 120006, 120007, 120008, 120009, 120010};
float price [SIZE] = {10.50, 5.50, 8.00, 12.10, 6.75, 5.20, 2.00, 4.45, 20.50, 10.00};
cout << "*************************************************************" << endl;
cout << "WELCOME TO THE CHECKOUT SYSTEM" << endl;
cout << "Please scan a barcode or manually enter the barcode ID number" << endl;
cout << "*************************************************************\n" << endl;
int newBarcode;
while (true){
cout << "Please enter a barcode (Type 'F' to finish): ", cin >> newBarcode;
int index = index_of(barcode, newBarcode, (sizeof(barcode) / sizeof(barcode)[0]));
cout << "\n>> Name of item: " << item[index] << endl;
cout << ">> Price of item: \x9C" << setprecision (4)<< price[index] << endl;
cout << ">> " <<item[index] << " has been added to your basket. \n" << endl;
float total = 0 + price[index];
cout << ">> Your current basket total is: \x9C" << setprecision(4) << total << endl;
/*float total = 0;
float newtotal = 0;
price[index] = total;
total = newtotal;
cout << ">> " << "Basket total: " << newtotal << endl; */
}
return 0;
}
You will need to iterate over all items and add their value to a variable. You can do it the old way:
float sum = 0;
for(int i = 0; i < SIZE; i++) {
sum += price [i];
}
Or the C++11 way:
float sum = 0;
for(float p : price) {
sum += p;
}
However I must point out a few important issues with your code:
Your array has a fixed size but user can enter as many entries as he wants. To avoid this issue, use vector. It behaves like array but has dynamic size. Simply use push_back() to add a new element.
Don't use separate containers (arrays) for the same group of objects. It's a bad coding practice. You can define a structure for product which will contain name, barcode and price, then make one container for all of the products.
Edit
I'm sorry, I misunderstood your problem. There are many ways to solve this, the most elegant way is to create a map where key is the bar code and value is your product object or just a price.
map<int, float> priceMap;
priceMap.insert(pair<int, float>([your bar code here], [your price here]))
Afterwards just create a vector of bar codes, fill it with user data and iterate over it sum all prices:
float sum = 0;
for(int b : userBarcodes) {
sum += priceMap.at(b);
}
You are trying to read from cin into an int. As you decide to put a stopping condition on 'F' input you must read into a string. Then decide what to do with the value. You will need to check if the input is an int or not. You can do it as given here or here.
Or you may change the stopping condition to a less likely integer like -1. And make sure you always read an int into newBarcode.
There are various small errors which are hard to list out. I have changed them in the code below which is implementing point 2 (You have to add the stopping condition).
One of the error or wrong practice is to declare new variables inside a loop. In most cases you can declare the variables outside and change there values in the loop.
I replaced (sizeof(barcode) / sizeof(barcode)[0] with SIZE as the lists are predefined and unchanging. Anyways you should use (sizeof(barcode) / sizeof(barcode[0]) for length calculation.
#include <iostream>
#include <iomanip>
using namespace std;
int index_of(int arr[], int item, int n) {
int i = 0;
while (i < n) {
if(arr[i] == item) {
return i;
}
i++;
}
return -1;
}
const int SIZE = 10;
int main()
{
string item [SIZE] = {"Milk", "Bread", "Chocolate", "Towel", "Toothpaste", "Soap", "Pen", "Biscuits", "Lamp", "Battery"};
int barcode [SIZE] = {120001, 120002, 120003, 120004, 120005, 120006, 120007, 120008, 120009, 120010};
float price [SIZE] = {10.50, 5.50, 8.00, 12.10, 6.75, 5.20, 2.00, 4.45, 20.50, 10.00};
cout << "*************************************************************" << endl;
cout << "WELCOME TO THE CHECKOUT SYSTEM" << endl;
cout << "Please scan a barcode or manually enter the barcode ID number" << endl;
cout << "*************************************************************\n" << endl;
int newBarcode;
float total = 0;
int index;
while (true){
cout << "Please enter a barcode (Type -1 to finish): \n";
cin >> newBarcode;
while(cin.fail()) {
cout << "Not an integer" << endl;
cin.clear();
cin.ignore(100,'\n');
cin >> newBarcode;
}
index = index_of(barcode, newBarcode, SIZE);
cout << index;
if (index == -1) {
cout << "Apologies here for unsupported barcode\n";
continue;
} else {
cout << ">> Name of item: " << item[index] << endl;
cout << ">> Price of item: " << price[index] << "\n";
cout << ">> " <<item[index] << " has been added to your basket. \n";
total = total + price[index];
cout << ">> Your current basket total is: " << total << "\n";
}
}
return 0;
}
Your question could be more helpful to others if you find out what is wrong with your implementation and ask implementation specific questions which will probably be already answered. Asking what is wrong with my code is not quite specific.

Possible to loop through an array structure in C++

Apologize ahead of time if this may have been answered previously. Didn't find anything (or wasn't using the correct search terms). Regardless, There is a specific part of my code I wanted to know if I could step through with a loop. I went ahead and added the code below. Two sections that I feel could probably be cleaned up is the request for user input for how much was spent on various budget categories. I had plan to use a for loop, but couldn't figure how to assign values to various elements of the MonthlyBudget structure "currentMonthlyBudget" (i.e. currentMonthlyBudget.housing, currentMonthlyBudget.utilities, etc). It would have worked for the expenseCategories[], but I could find how (or if it is possible) to do it for the structure. Any assistance would be appreciated. Thanks in advance.
/* Exercise_10.cpp Monthly Budget Calculation*/
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
using namespace std;
struct MonthlyBudget
{
double housing; //Housing
double utilities; //Utilities
double householdExpense; //Household Expense
double transportation; //Transportation
double food; //Food
double medical; //Medical
double insurance; //Insurance
double entertainment; //Entertainment
double clothing; //Clothing
double misc; //Miscellaneous
};
int main()
{
//Array of Monthly Budget Values
double defaultMonthlyBudget[10] = { 500.00, 150.00, 65.00,
50.00, 250.00, 30.00,
100.00, 150.00, 75.00,
50.00 };
//Array of Expense Categories
string expenseCategories[10] = { "Housing Accomodations", "Utilities", "Household Expenses",
"Transporation", "Food", "Medical Expenses", "Insurance",
"Entertainment", "Clothing", "Miscellaneous Expenses" };
//Array to hold the over budget and under budget values
double actualBudget[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//Accumulator for actual budget
double sum = 0.00;
//Loop counter
int index;
//Final Total Budget
double calculatedTotalBudget = 0.00;
//Structure
MonthlyBudget currentMonthlyBudget;
cout << "Greetings. This program will determine if you are meeting your agreed upon budget." << endl;
cout << "I will ask you questions about your spending habits, and return a report to see how\n";
cout << "you did this month. Lets get started!\n\n\n";
cout << "\nPlease type in how much was spent this month for " << expenseCategories[0] << ": ";
cin >> currentMonthlyBudget.housing;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[1] << ": ";
cin >> currentMonthlyBudget.utilities;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[2] << ": ";
cin >> currentMonthlyBudget.householdExpense;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[3] << ": ";
cin >> currentMonthlyBudget.transportation;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[4] << ": ";
cin >> currentMonthlyBudget.food;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[5] << ": ";
cin >> currentMonthlyBudget.medical;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[6] << ": ";
cin >> currentMonthlyBudget.insurance;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[7] << ": ";
cin >> currentMonthlyBudget.entertainment;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[8] << ": ";
cin >> currentMonthlyBudget.clothing;
cout << "\nPlease type in how much was spent this month for " << expenseCategories[9] << ": ";
cin >> currentMonthlyBudget.misc;
cout << "\n\n\n";
//Compare inputted values to those of the predetermine budget
actualBudget[0] = (defaultMonthlyBudget[0] - currentMonthlyBudget.housing);
actualBudget[1] = (defaultMonthlyBudget[1] - currentMonthlyBudget.utilities);
actualBudget[2] = (defaultMonthlyBudget[2] - currentMonthlyBudget.householdExpense);
actualBudget[3] = (defaultMonthlyBudget[3] - currentMonthlyBudget.transportation);
actualBudget[4] = (defaultMonthlyBudget[4] - currentMonthlyBudget.food);
actualBudget[5] = (defaultMonthlyBudget[5] - currentMonthlyBudget.medical);
actualBudget[6] = (defaultMonthlyBudget[6] - currentMonthlyBudget.insurance);
actualBudget[7] = (defaultMonthlyBudget[7] - currentMonthlyBudget.entertainment);
actualBudget[8] = (defaultMonthlyBudget[8] - currentMonthlyBudget.clothing);
actualBudget[9] = (defaultMonthlyBudget[9] - currentMonthlyBudget.misc);
//TEST
/*for (index = 0; index < 10; index++)
{
cout << actualBudget[index] << "\n";
}*/
//Add up actualBudget
for (index = 0; index < 10; index++)
{
sum += actualBudget[index];
}
//Assign value to Calculated Total Budget
calculatedTotalBudget = (1420.00 - sum);
//Loop to display what categories we went over, under, & met our budget
for (index = 0; index < 10; index++)
{
if (actualBudget[index] < 0.00)
{
cout << "For the category of " << expenseCategories[index] << ", you went over your budget by $" << abs(actualBudget[index]) << ".\n";
}
else if (actualBudget[index] > 0.00)
{
cout << "For the category of " << expenseCategories[index] << ", you came in under your budget by $" << abs(actualBudget[index]) << ".\n";
}
else
{
cout << "For the category of " << expenseCategories[index] << ", you met your budget exactly.\n";
}
}
//Provide information to the user if the grand total went over, under, or met our total budget
if (calculatedTotalBudget > 1420.00)
{
cout << "This month's total expenditure was $" << calculatedTotalBudget << ". You were over budget by $" << (calculatedTotalBudget - 1420.00) << ".\n";
}
else if (calculatedTotalBudget < 1420.00)
{
cout << "This month's total expenditure was $" << calculatedTotalBudget << ". You were under budget by $" << abs(1420.00 - calculatedTotalBudget) << ".\n";
}
else
{
cout << "This month's total expenditure was $" << calculatedTotalBudget << ". You met your budget exactly.\n";
}
}
A clean solution could be to just hold a vector of categories and references to the values they map to
//Array of Expense Categories
std::vector<std::pair<string, double&>> expenseCategories = {
{ "Housing Accomodations", currentMonthlyBudget.housing },
{ "Utilities", currentMonthlyBudget.utilities },
{ "Household Expenses", currentMonthlyBudget.householdExpense },
{ "Transporation", currentMonthlyBudget.transportation },
{ "Food", currentMonthlyBudget.food },
{ "Medical Expenses", currentMonthlyBudget.medical },
{ "Insurance", currentMonthlyBudget.insurance },
{ "Entertainment", currentMonthlyBudget.entertainment },
{ "Clothing", currentMonthlyBudget.clothing },
{ "Miscellaneous Expenses", currentMonthlyBudget.misc }
};
Any loop will then just use either the category description or the value it maps to
for (auto& category : expenseCategories) {
cout << "\nPlease type in how much was spent this month for " << category.first << ": ";
cin >> category.second;
}
Live Example
The solution above has the advantage that you can reorganize your fields as you wish and just update the references involved.
For a simple data structure like the one you have you might as well have referred to its fields as in a simple array (i.e. by getting the pointer to the first element and then iterating over those).
If you really want to make a for loop from the MonthlyBudget input, you can do it by creating an array of a simple struct:
struct BudgetInputInfo {
std::string message;
double& targetValue;
}
Just create a static array of this, and you can write your for loop based on that array.
You can even add a method to this struct which displays the message, and sets targetValue.
Later, when you have other members than doubles, you can change this into a template.
But I think this won't result in the most readable code, you won't get a real benefit from the for loop, unless you want to be able to change the list it's based on runtime.
If your list is fixed like in the example, creating a function which prints out the message and reads the input would be more readable:
void readInput(std::string targetName, double& target) {
cout << "Please type in how much was spent this month for " << targetName << ": ";
cin >> target;
cout << endl;
}
With this, you would only have a few relatively short readInput calls.
You can even make a function which reads every member of a MonhtlyBudget:
void readMonhtlyBudget(MonthlyBudget& m) {
readInput("Housing Accomodations", m.housing);
// ...
}
Also, I would change your 10 element arrays to be instances of MonthlyBudgets. It's more clear, and you can even keep your current initializer syntax if you are using C++11:
MonthlyBudget defaultBudget = { 500.00, 150.00, 65.00,
50.00, 250.00, 30.00,
100.00, 150.00, 75.00,
50.00 };
And move the difference calculation code into a separate method, preferrable operator-:
MonthlyBudget operator-(MonthlyBudget const& a, MonthlyBudget const& b) {
MonthlyBudget result;
result.housing = a.housing - b.housing;
// ...
return result;
}
With these changes, you can just write:
actualBudget = defaultBudget - currentMonthlyBudget;

What container to use when I need to know both the max value and who has achieved it?

I'm trying to work through the beginner exercises from a website.
"Requires:
variables, data types, and numerical operators
basic input/output
logic (if statements, switch statements)
loops (for, while, do-while)
arrays
Write a program that asks the user to enter the number of pancakes eaten for breakfast by 10 different people (Person 1, Person 2, ..., Person 10)
Once the data has been entered the program must analyze the data and output which person ate the most pancakes for breakfast."
I'm unsure on how to get the program to call out the person which enters the most number of pancakes eaten? Surely this would need to be done with a key and value, but the requirements state 'arrays' but not 'maps'?
Below is the code I have come up with, but this only outputs the maximum number of pancakes eaten, so not really answering the question!
Thanks so much for any help!
* I've only used 5 people to quicken the process before I know exactly how to do it *
#include <iostream>
using namespace std;
int main()
{
cout << "how many pancakes did you eat for breakfast?" << endl;
int person1, person2, person3, person4, person5;
cout << "Person 1: ";
cin >> person1;
cout << "Person 2: ";
cin >> person2;
cout << "Person 3: ";
cin >> person3;
cout << "Person 4: ";
cin >> person4;
cout << "Person 5: ";
cin >> person5;
int array[5] = {person1, person2, person3, person4, person5};
int temp = 0;
for (int i = 0; i<5; i++)
{
if (array[i] > temp)
{
temp = array[i];
}
}
cout << "The most pancakes eaten was " << temp << "by " << endl;
}
Surely this would need to be done with a key and value
This is not the only way of doing it. Another way is to use an indexed collection with no key, and make an assumption that position k corresponds to a key k that can be computed from a position alone. For example, if you have an array of ten items corresponding to ten people numbered 1 through 10, then the data for a person number k could be stored in the array at position k-1. No keys are required in this situation.
This long explanation means that if you store the best i in addition to best tmp, you'll have your answer after the loop:
int temp = 0;
int res = -1;
for (int i = 0; i<5; i++) {
if (array[i] > temp) {
temp = array[i];
res = i;
}
}
cout << "The most pancakes eaten was " << temp << "by " << (res+1) << endl;
Note the res+1 is printed, not res. This is because arrays are zero-based, while counting is one-based.
This could be further shortened using a common idiom of using the initial element as the current best, and starting your iterations from 1:
int res = 0;
for (int i = 1 ; i<5 ; i++) {
if (array[i] > array[res]) {
res = i;
}
}
cout << "The most pancakes eaten was " << array[res] << "by " << (res+1) << endl;
What if you kept track of the maximum amount of pancakes eaten as you took input?
#include <iostream>
using namespace std;
// To execute C++, please define "int main()"
int main() {
int numPeople = 5;
int maxPancakes = -1;
int maxPerson = -1;
int currentPancakes = -1;
for (int i = 1; i < numPeople; i++) {
cout << "Person " << i << ": ";
cin >> currentPancakes;
if (currentPancakes > max) {
max = currentPancakes;
maxPerson = i;
}
}
cout << "Person " << maxPerson << " ate the most pancakes: " << maxPancakes;
return 0;
}
Note: my c++ is pretty rusty, I haven't tested this solution. Just an idea ;)
Using Map for this question will be an overkill. Array is more than enough. You don't even need to iterate through the array to check who ate the most. The operation for getting the max is actually O(0) because we can update who ate the most as you are entering the values.
int main(){
const int NUM_PEOPLE = 10;
int cakesEaten[10] = {0};
int maxEaten = 0;
int personId = 0;
cout << "How many pancakes eaten by:" << endl;
for(int x=0; x<NUM_PEOPLE; x++){
cout << "person " << (x+1) << ":";
cin >> cakesEaten[x];
if (cakesEaten[x] > maxEaten){
maxEaten = cakesEaten[x];
personId = x;
}
}
cout << "The most pancakes was eaten by person " << personID << endl;
}
You don't need any storage at all.
As the numbers are entered, compare them and store who has the current max, and its value
Starting with fake values is not needed if you use the first person's value as the start value, this way negative values, could be included if entered. That may be nonsensical here, but in general, its a better practice.
Also note if we want people to start at 1, then it makes more sense to start it at 1, then start at 0 and try to remember to always add 1.
This is also very easy to expand to more people, just change total_people
int main() {
const int total_people=5;
cout << "how many pancakes did you eat for breakfast?" << endl;
int what;
cout << "Person 1: ";
cin >> what;
int who=1;
int max_value=what;
for (int person = 2; person <= total_people; ++person) {
cout << "Person " << person << ": ";
cin >> what;
if (what > max_value) {
max_value=what;
who=i;
}
}
cout << "The most pancakes eaten was " << max_value << "by " << who << endl;
}

Functions and structures in C++

/*I got stumped within my code. I think classes will be simpler than structures, but the chapter within my book makes me do structures. : / I am currently getting an error message that my function was not matched up for an overloaded function. The book does talk about them, but the examples of overloading functions in the book aren't helping me out. Also the book wants me to enter account numbers and fill in the objects and when they are asked for an account number they should have the opportunity to "QUIT" entering numbers and proceed onto the next part of the program; that whole way of thinking has my brain a bit fried and I was hoping I could get some help. I apologize if the formatting of my code is messy, I tried to reformat it within here so it would all go into the code brackets.
The Error happens at line... 161 at the displayAccounts function. Parameters were different within the top and bottom of the two functions I changed it and it works. I am going to go over different parts and if its correct post the correct code.*/
I figured out exactly the question that I need. I need the "QUIT" loop to be allowed to be followed up within the account numbers. This would allow the user to enter in a 0 at any time when asked to enter an account number and this was what was confusing me the most.
#include <iostream>
#include <iomanip>
using namespace std;
struct BankAccount
{
void enterAccountsData(BankAccount *accounts);
void computeInterest(BankAccount *accounts);
void displayAccounts(BankAccount *accounts, const int QUIT);
int accountNum; // holds the account number.
double accountBal; // holds the account balance.
double annualInterest; // holds the interest rate.
int term; // holds the term for the accounts.
};
int main()
{
const int MAX_ACCOUNTS = 100; // The maximum number of bank accounts.
const int QUIT = 0; // sentinal value.
int input;
int num = 0;
BankAccount data[MAX_ACCOUNTS];
BankAccount display;
cout << "Enter " << QUIT << " to stop, otherwise enter 1 and procreed.";
cin >> input;
while(true)
{
if(input != QUIT)
{
data[MAX_ACCOUNTS].enterAccountsData(data);
data[MAX_ACCOUNTS].computeInterest(data);
}
else
{
break;
}
}
display.displayAccounts(data, QUIT);
//system("pause");
return 0;
}
void BankAccount::enterAccountsData(BankAccount *accounts)
{
cout << setprecision(2) << fixed;
const int NUM_OF_ACCOUNTS = 100; // the number of bank accounts. (change the number for more bank accounts)
int found;
int quit = 0;
/* First for loop which asks and holds the account information
entered in by the user. */
for(int num = 0; num < NUM_OF_ACCOUNTS; num++)
{
do
{
found = 0;
cout << "Enter in account # " << (num + 1) << endl;
cin >> accounts[num].accountNum; // holds the value of the account number
// Checks if the account number is valid.
while(accounts[num].accountNum < 999 || accounts[num].accountNum > 10000)
{
cout << "Account number must be four didgets:" << endl;
cin >> accounts[num].accountNum;
}
// Checks if the account numbers are the same.
for(int check = 0; check < num; check++)
{
while(accounts[num].accountNum == accounts[check].accountNum)
{
cout << endl << "Account Numbers cannot be the same, enter in a new account number." << endl;
found = 1;
break;
}
}
} while(found); // end of do while.
// Holds the values for the account balances.
cout << "Enter the accounts balance." << endl;
cin >> accounts[num].accountBal;
// Makes sure that the account balance is not negative.
while(accounts[num].accountBal < 0)
{
cout << "Account cannot have a negitive balance." << endl;
cin >> accounts[num].accountBal;
}
// Holds the interest rate.
cout << endl << "Enter the interest rate for account # " << (num + 1) << endl;
cin >> accounts[num].annualInterest;
// Makes sure the interest rate is valid
while(accounts[num].annualInterest > 0 && accounts[num].annualInterest > 0.15)
{
cout << endl << "Annual interest must be from 0 to 0.15." << endl;
cin >> accounts[num].annualInterest;
}
// Makes sure the interest rate is not negetive
while(accounts[num].annualInterest < 0)
{
cout << endl << "Interest rate cannot be negetive" << endl;
cin >> accounts[num].annualInterest;
}
// Holds the value for the length of the interest.
cout << endl << "How many years will this interest rate be held for? " << endl;
cin >> accounts[num].term;
//Checks for valid length of time for the term held
while(accounts[num].term < 0 || accounts[num].term > 11)
{
cout << "The Term must be greater than 1 and should not exceed 10" << endl;
cin >> accounts[num].term;
}
}
cout << "If you wish to stop enter 0 otherwise type 1 to proceed" << endl;
cin >> quit;
if(quit = 0)
{
return;
}
}
void BankAccount :: computeInterest(BankAccount *accounts)
{
const int NUM_OF_ACCOUNTS = 100; // the number of bank accounts.
const int MONTHS_IN_YEAR = 12;
double total = 0;
double average = 0;
for(int num = 0; num < NUM_OF_ACCOUNTS; num++)
{
/*Goes through the term year and calculates the total
of each account balance. Then calculates the average. */
for(int year = 0; year < accounts[num].term; year++)
{
for(int month = 0; month < MONTHS_IN_YEAR; month++)
{
accounts[num].accountBal = (accounts[num].accountBal * accounts[num].annualInterest) + accounts[num].accountBal;
}
int month = 1;
cout << endl << "Total amount for account # " << (num + 1) << " is: " << accounts[num].accountBal << endl ;
total += accounts[num].accountBal;
cout << endl << "The total amount of all accounts is: " << total << endl;
}
}
average = total / NUM_OF_ACCOUNTS;
cout << "Average of all the bank accounts is: " << average << endl;
}
void BankAccount :: displayAccounts(BankAccount *accounts)
{
int input = 0;
int found;
const int MAX_ACCOUNTS = 100;
int quit = 0;
cout << endl << "Which account do you want to access?" << endl <<
"To stop or look at none of the account numbers type: " << quit << endl;
cin >> input;
for(int num = 0; num < MAX_ACCOUNTS; num++)
{
while(num < MAX_ACCOUNTS && input != accounts[num].accountNum)
{
num++;
}
if(input == accounts[num].accountNum) // This if sees if an account matches what the user entered.
{
cout << "Account: " << accounts[num].accountNum << endl << "Balance is: " <<
accounts[num].accountBal << endl << "Interest rate is: " << accounts[num].annualInterest;
cout << endl << "Enter another account number or type 0 to quit." << endl;
found = 1;
cout << endl;
cin >> input;
}
if(found == 0)
{
cout << "Sorry that account doesn't exist. Enter another account number." << endl;
cin >> input;
}
}
}
In C++, classes and structs are exactly the same constructs. They are, in fact, one thing — a User-Defined Type.
There is a different that is invoked depending on whether you used the keyword struct or class to define your UDT, and that is that class-key defaults to private member access and private inheritance, whereas struct-key defaults to both being public.
Other than this syntax difference, you can use either without worrying about one being "simpler" than the other.
Anyway, your compiler error (please provide it next time) is probably due to a declaration/definition mismatch.
Your declaration:
void displayAccounts(BankAccount *accounts, const int QUIT);
Start of your definition:
void BankAccount :: displayAccounts(BankAccount *accounts) {
The start of the definition should be
void BankAccount::displayAccounts(BankAccount* accounts, const int QUIT) {
to match. I've also fixed your spacing to be nicer. :)
void displayAccounts(BankAccount *accounts, const int QUIT);
... looks different between declaration and definition. Second parameter is missing in the definition.
Not sure what your question is, but classes and structs in C++ are equivalent except that fields are public by default in structs, but private by default in classes.
In the struct’s displayAccounts() member declaration you have:
void displayAccounts(BankAccount *accounts, const int QUIT);
and when defining the method later:
void BankAccount :: displayAccounts(BankAccount *accounts)
You have just missed
const int QUIT
parameter for the member function definition.