I have a program with car rental information and the company as well. I am trying to read it in and have it display on the terminal. However, I am only getting one company to print clearly, while the others print out only trash. I want to store the agencies with a car inventory of 5 as well, but don't exactly know how to store them without having all my information read in yet. I can only use C-Style strings also.
Here is the file I am reading in:
Hertz 93619
2014 Toyota Tacoma 115.12 1
2012 Honda CRV 85.10 0
2015 Ford Fusion 90.89 0
2013 GMC Yukon 110.43 0
2009 Dodge Neon 45.25 1
Alamo 89502
2011 Toyota Rav4 65.02 1
2012 Mazda CX5 86.75 1
2016 Subaru Outback 71.27 0
2015 Ford F150 112.83 1
2010 Toyota Corolla 50.36 1
Budget 93035
2008 Ford Fiesta 42.48 0
2009 Dodge Charger 55.36 1
2012 Chevy Volt 89.03 0
2007 Subaru Legacy 59.19 0
2010 Nissan Maxima 51.68 1
Section of my code where I need help:
#include <iostream>
#include <fstream>
using namespace std;
struct car
{
char agency[10];
int zip;
int year;
char make[10];
char model[10];
float price;
int available;
} ;
struct agency
{
char company[10];
int zip;
int inventory[5];
};
void menu();
// Main Function
int main ()
{
// declare variables
const int carAmount = 15;
int agencyAmount = 1;
int choice;
agency agencyLib[carAmount];
car carLib[carAmount];
char filename[10];
ifstream carInData;
bool menu1 = false;
//prompt user for input file
cout << " Enter file name: ";
cin >> filename;
// Start loop menu
while(menu1 = true)
{
menu();
carInData.open(filename);
cin >> choice;
if (carInData.is_open())
{
// read list of names into array
for (int count = 0; count < agencyAmount; count++)
{
carInData >> agencyLib[count].company >> agencyLib[count].zip;
for (count = 0; count < carAmount; count++)
{
carInData >> carLib[count].year >> carLib[count].make >> carLib[count].model >> carLib[count].price >> carLib[count].available;
}
}
}
switch (choice)
{
// Case 1 closes menu
case 1:
return 0;
break;
// Case 2 displays if car is available if 1, unavailable if 0
case 2:
// itterate through car array
for(int count = 0; count < agencyAmount; count++)
{
cout << agencyLib[count].company << " " << agencyLib[count].zip << "\n";
for(int count = 0; count < carAmount; count++)
{
// Displays if car is available or not
/* if (carLib[count].available == 1)
cout << " Available ";
else
cout << " Unavailable ";
*/
// Display Cars
cout << carLib[count].year << " " << carLib[count].make << " " << carLib[count].model << " " << carLib[count].price << " " << "\n";
}
}
}
}
}
As a general preliminary remark, I think that even for learning purpose, this kind of exercise should better let you use std::strings instead of c-strings and std::vector for keeping a growing number of items.
What's wrong in your code ?
The first problem is that you use the same counter count to populate your agency array AND the car array. This will cause you very quickly to have a counter beyond the array boundaries and corrupt memory.
Solution: rework your loop structure using 2 distinct counters.
Next problem is that you don't identify the end of the car list of an agency. This makes it unrealistic to read more than one agency: you'll experience a failure on the stream reading that will prevent you getting anything usefull in your data.
Solution: analyze failures on reading to identify going from cars ( first element should be a number) to a new agency ( first element is a string).
In addition, you might have some strings which are longer than allowed by your character arrays, causing further memory corruption.
Solution: limit the number of chars read using iomanip() to fix maximum width. This is strongly recommended unless you go for std::string
Last issue: the variable length arrays are not a standard C++ feature, even if some popular compilers support it.
Solution: Either use dynamic allocation with new/delete or opt for the purpose of this excercise to use a constant maximum size.
Code snippet:
Adapted, without choices, menus, etc. , the reading would look like:
const int carAmount = 30; // !!!
const int agencyAmount = 10; // !!!
agency agencyLib[carAmount];
car carLib[carAmount];
ifstream carInData ("test.dat");
int numCar = 0, numAgency = 0; // !!! shows the real number of items available
int count1, count2; //
cout << "Start reading" << endl;
for (numAgency = numCar = 0; carInData && numAgency < agencyAmount; numAgency++) {
if (!(carInData >> setw(sizeof(agencyLib[numAgency].company)) >> agencyLib[numAgency].company >> agencyLib[numAgency].zip))
break; // if nothing left, exit loop immediately
for (; numCar < carAmount; numCar++) {
carInData >> carLib[numCar].year >> setw(sizeof(carLib[numCar].make )) >>carLib[numCar].make
>> setw(sizeof(carLib[numCar].model))>>carLib[numCar].model
>> carLib[numCar].price >> carLib[numCar].available;
if (carInData.fail()) { // here we expect a year, but get an agency string
carInData.clear();
break;
}
strcpy(carLib[numCar].agency, agencyLib[numAgency].company);
carLib[numCar].zip = agencyLib[numAgency].zip;
}
}
And the subsequent display:
cout << "Display agencies: " << endl;
for (count1 = 0; count1 < numAgency; count1++) {
cout << agencyLib[count1].company << " " << agencyLib[count1].zip << "\n";
}
cout << "Cars: " << endl;
for (count2 = 0; count2 < numCar; count2++) {
cout << carLib[count2].agency << " " << carLib[count2].zip << ": ";
cout << carLib[count2].year << " " << carLib[count2].make << " " << carLib[count2].model << " " << carLib[count2].price << " " << "\n";
}
Note that there's no link beteween agencies and cars (except the common fields), so the display just shows two distinct lists.
Related
I am new to C++.
Below is code that lets a user enter five elements into an array, then sums those values, and obtains the mean and a predicted future value.
The code works fine if the user enters five elements, but how do I handle the situation in which one or more values are missing?
I have written code further below that seems to solve this problem, by defining a missing value to be a negative number. That code also seems to work fine. But, is there a better, accepted way of handling missing values in a C++ array?
If I try to run the first code in Microsoft Visual Studio 2019, I do not even know what to enter for a missing value. If I do not enter anything, and just press the Enter key, nothing happens.
Here is the original code that works with five elements. This code is slightly modified from code written by Saldina Nurak:
#include <iostream>
using namespace std;
int nmonths = 6;
int totalmonths = 24;
int main()
{
// {100, 220, 300, 0, 200, 250}
// This line works in the command window
// float monthArray[nmonths];
// for Microsoft Visual Studio 2019
float monthArray[6];
float total = 0;
for(int i = 0; i <= (nmonths-1); i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> monthArray[i];
total += monthArray[i];
}
float average = total / nmonths;
float inTwoYears = average * totalmonths;
cout << "total = " << total << endl;
cout << "average = " << average << endl;
cout << "inTwoYears = " << inTwoYears << endl;
}
Enter Amount 1: 100
Enter Amount 2: 220
Enter Amount 3: 300
Enter Amount 4: 0
Enter Amount 5: 200
Enter Amount 6: 250
total = 1070
average = 178.333
inTwoYears = 4280
Here is the modified code I wrote that seems to handle missing values, by defining them to be negative numbers:
#include <iostream>
using namespace std;
int nmonths = 6;
int totalmonths = 24;
int emptycounter = 0;
int main()
{
// This works from the command window
// float monthArray[nmonths]; // {100, 220, 300, 0, -99, 250};
// for Microsoft Visual Studio I have to use
float monthArray[6];
float total = 0;
for(int i = 0; i <= (nmonths-1); i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> monthArray[i];
if (monthArray[i] >= 0) emptycounter++;
else (emptycounter = emptycounter);
if (monthArray[i] >= 0) total += monthArray[i];
else total = total;
}
float average = total / emptycounter;
float inTwoYears = average * (totalmonths - (nmonths - emptycounter));
cout << "total = " << total << endl;
cout << "average = " << average << endl;
cout << "inTwoYears = " << inTwoYears << endl;
}
C:\Users\mark_>cd C:\Users\mark_\myCppprograms
C:\Users\mark_\myCppprograms>c++ MissingDataInArray2.cpp -o MissingDataInArray2.exe -std=gnu++11
C:\Users\mark_\myCppprograms>MissingDataInArray2
Enter Amount 1: 100
Enter Amount 2: 220
Enter Amount 3: 300
Enter Amount 4: 0
Enter Amount 5: -99
Enter Amount 6: 250
total = 870
average = 174
inTwoYears = 4002
What is the standard approach for dealing with missing values in C++ and how does a user enter a missing value from the keyboard?
You would have to define what is supposed to be a missing value if you are trying to read as a number. You could maybe read the line and try to parse it to a int and if unable to parse then it would be your missing value?
Also, you are not using C++ arrays, you are using C arrays.
C++ has an array container but vector gives you much more flexibility.
You could do something like this:
vector<int> monthArray;
int value;
for(int i = 0; i < nmonths; i++) // See the change done in the test
{
cin >> value;
if(value > 0)
monthArray.push_back(value); // This would insert at the end and take care of resizing the container as needed.
}
monthArray.size(); // This returns how many elements you have in the container
Both your else clauses are assigning a variable to itself. You can erase both and put the 2 statements inside the same if:
if (monthArray[i] >= 0)
{
emptycounter++;
total += monthArray[i];
}
But if you use vector you won't need emptycounter. The size of the vector will contain the number of valid elements.
for(int i = 0; i < nmonths; i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> value;
if(value > 0)
{
monthArray.push_back(value);
total += value;
}
}
After all that... There is this question: Do you really need an array? You just seem to accumulate the valid values and never refer to the array after saving the elements on it.
P.S: to use vector you need to #include<vector>
What is the standard approach for dealing with missing values in C++ ?
std::optional is standard and serves the need.
How does a user enter a missing value from the keyboard?
There is no definition of operator>> for istream and std::optional<float> but you can write a function that behaves the way you want.
For example you could use std::getline to always read an entire line, then if the line is blank return an empty std::optional<float> and if not then parse the number and return a std::optional<float> that contains it.
Here is code that implements the answer from #vmp when missing observations are defined as NA (as in R and suggested by #Yksisarvinen in a comment) by using stoi. I have not yet figured out how to implement the answer from #Ben Voigt.
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int nmonths = 6 ;
int totalmonths = 24 ;
int main()
{
float total = 0;
vector<int> monthArray;
string value;
for(int i = 0; i < nmonths; i++)
{
cout << "Enter Amount " << i+1 << ": ";
cin >> value;
if(value != "NA")
{
monthArray.push_back(stoi(value));
total += stoi(value);
}
}
float average = total / monthArray.size() ;
float inTwoYears = average * (totalmonths - (nmonths - monthArray.size())) ;
cout << "total = " << total << endl;
cout << "average = " << average << endl;
cout << "inTwoYears = " << inTwoYears << endl;
}
// C:\Users\mark_>cd C:\Users\mark_\myCppprograms
// C:\Users\mark_\myCppprograms>c++ vector2.cpp -o vector2.exe -std=gnu++11
// C:\Users\mark_\myCppprograms>vector2
// Enter Amount 1: 100
// Enter Amount 2: 220
// Enter Amount 3: 300
// Enter Amount 4: 0
// Enter Amount 5: NA
// Enter Amount 6: 250
// total = 870
// average = 174
// inTwoYears = 4002
Structure and DMA. I want to retrieve all the inserted record in decreasing order of cgpa.
Without sorting it give the result as shown below image.
#include<iostream>
#include<string>
using namespace std;
struct student {
string name;
int age;
float cgpa;
};
void main()
{
student *ptr;
int size;
cout << "enter size \n";
cin >> size;
ptr = new student[size];
for (int i = 0; i < size; i++)
{
cout << "enter student " << i + 1 << " name\n";
cin >> ptr[i].name;
cout << "enter student " << i + 1 << " age\n";
cin >> ptr[i].age;
cout << "enter student " << i + 1 << " cgpa\n";
cin >> ptr[i].cgpa;
}
cout << "with out sorting \n";
for (int i = 0; i < size; i++)
{
cout << " NAME\tAGE\tCGPA\n";
cout << ptr[i].name << "\t" << ptr[i].age << "\t" << ptr[i].cgpa << endl;
}
system("pause");
}
[1]: https://i.stack.imgur.com/whP8d.png
"Without sorting" is a bit unclear, but I take that to mean you cannot call std::sort directly or use another explicit sorting routine. That leaves you with choosing a container that stores object in sort order based on a compare function (or overload) you provide. Looking at the Microsoft C++ language conformance table for VS2015, it shows all core language features for C++11 supported -- which would include std::set.
std::set allows you to store a sorted set of unique objects. This means you can take input and store the results in a std::set based a Compare function you provide. Providing a Compare function that will compare the cgpa of each student will then automatically store your student objects based cgpa.
To make std::set available, you simply need to #include<set>. Writing the compare function that can be used to store students based on cgpa simply requires providing an overload for the < operator that takes two of your student objects as arguments and then returns true when the first argument sorts before the second, false otherwise. That can be as simple as:
/* overload of < comparing student by cgpa */
bool operator <(const student& a, const student& b) {
return a.cgpa < b.cgpa;
}
A note: unless you are compiling for a micro-controller or embedded system with no Operating System (called a freestanding environment), void main() is wrong. A standard conforming invocation of main() is either int main(void) or int main (int argc, char **argv) where argc is the argument count and argv your argument vector (technically an array of pointers to null-terminated strings where the next pointer after the last argument is set to NULL as a sentinel) There are other non-standard extensions added by some compilers like char **envp providing a pointer to each of the environment variables.
To declare your set of student you need to provide the type student and the compare function to be used when inserting students into your set. Since you provide an overload for the less-than operator, you can use std::less<> providing one template argument, e.g.
int main(void)
{
/* create std::set of students using std::less for compare */
std::set<student, std::less<const student&>> students {};
And since you are using a container that provides automatic memory management for you, there is no need to know the size (or number of students to enter) before hand. You can simply enter as many students as you need and then press Ctrl+d on Linux or Ctrl+z on Windows to generate a manual EOF signifying your end of input. However you do need to validate every user input by checking the return (stream state) following each input. At minimum you can use:
std::cout << "enter student " << i + 1 << " name\n";
if (!(std::cin >> s.name)) /* validate all input, ctrl + z to end input */
break;
(note: the variable i is only needed to show the student number when you prompt for input, all containers provides the .size() member function that tell you how many objects are contained within.)
When done taking input, you can use a Range-based for loop to iterate over each student in your set outputting the desired information. For example:
std::cout << "\nwith out sorting \n";
for (auto& s : students) { /* output in order of cgpa w/o sorting */
std::cout << " NAME\tAGE\tCGPA\n"
<< s.name << "\t" << s.age << "\t" << s.cgpa << '\n';
}
Putting it altogether, you could do:
#include <iostream>
#include <string>
#include <set>
struct student { /* struct student */
std::string name;
int age;
float cgpa;
};
/* overload of < comparing student by cgpa */
bool operator <(const student& a, const student& b) {
return a.cgpa < b.cgpa;
}
int main(void)
{
/* create std::set of students using std::less for compare */
std::set<student, std::less<const student&>> students {};
for (int i = 0; ; i++) {
student s {}; /* temporary struct to add to set */
std::cout << "enter student " << i + 1 << " name\n";
if (!(std::cin >> s.name)) /* validate all input, ctrl + z to end input */
break;
std::cout << "enter student " << i + 1 << " age\n";
if (!(std::cin >> s.age))
break;
std::cout << "enter student " << i + 1 << " cgpa\n";
if (!(std::cin >> s.cgpa))
break;
students.insert(s); /* insert student in set */
}
std::cout << "\nwith out sorting \n";
for (auto& s : students) { /* output in order of cgpa w/o sorting */
std::cout << " NAME\tAGE\tCGPA\n"
<< s.name << "\t" << s.age << "\t" << s.cgpa << '\n';
}
}
(note: Look at Why is “using namespace std;” considered bad practice?. Developing good habits early is a lot easier that trying to break bad ones later...)
(note 2: you might consider using getline(std::cin, s.name) to take input for the student name so you can handle names with spaces, like Firstname Lastname, e.g. Mickey Mouse, up to you)
Add system("pause"); back in to hold your terminal window open as needed.
Example Use/Output
Now just enter the student data for as many students as you like and then terminate input by generating a manual EOF as described above, e.g.
$ ./bin/set_student_grades
enter student 1 name
gates
enter student 1 age
20
enter student 1 cgpa
2.12
enter student 2 name
della
enter student 2 age
21
enter student 2 cgpa
2.00
enter student 3 name
jim
enter student 3 age
30
enter student 3 cgpa
3.12
enter student 4 name
with out sorting
NAME AGE CGPA
della 21 2
NAME AGE CGPA
gates 20 2.12
NAME AGE CGPA
jim 30 3.12
This provides a way to store and provide the student data in order of cgpa without an explicit sort. Of course std::set does that for you, but if avoiding an explicit sort was the intent of your program, this is very good option. Let me know if you have further questions.
#include<iostream>
#include<string>
using namespace std;
struct student {
string name;
int age;
float cgpa;
};
void main() {
student *ptr;
int size;
cout << "enter size \n"; cin >> size;
ptr = new student[size];
for (int i = 0; i < size; i++)
{
cout << "enter student " << i + 1 << " name\n";
cin >> ptr[i].name;
cout << "enter student " << i + 1 << " age\n";
cin >> ptr[i].age;
cout << "enter student " << i + 1 << " cgpa\n";
cin >> ptr[i].cgpa;
}
string temp1; int temp2; float temp3;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (ptr[i].cgpa < ptr[j].cgpa)
{
temp1 = ptr[j].name;
ptr[j].name = ptr[i].name;
ptr[i].name = temp1;
temp2 = ptr[j].age;
ptr[j].age = ptr[i].age;
ptr[i].age = temp2;
temp3 = ptr[j].cgpa;
ptr[j].cgpa = ptr[i].cgpa;
ptr[i].cgpa = temp3;
}
}
}
for (int i = 0; i < size; i++) {
cout << " NAME\tAGE\tCGPA\n";
cout << ptr[i].name << "\t" << ptr[i].age << "\t" << ptr[i].cgpa << endl;
}
delete[] ptr;
system("pause");
}
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.
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;
}
I have an assignment where we need to have 2 parallel arrays one is a list of city names and the other is sales amounts. Here is a copy of the problem:
Program Description:
It needs to compile sales totals for various cities in the USA. Specifically, when the program is run, the user will be prompted to enter a city. If the city is correct, the user will then be prompted to enter a sales amount. If the city doesn’t exist on the list, the user will get an error message (and no sales amount prompt). If a sales amount is entered, it will accumulate into a total for that city. Either way (city exists on the list or not) , the user will then be asked to enter another city or quit.
Once the user quits, the city name and total should be displayed for all cities, one per line. Following that the program should stop.
There are only 8 cities to choose from. 2 parallel arrays must be used, initialized as follows:
City (String) Sales (Integer)
------------- ---------------
Atlanta 0
Buffalo 0
Chicago 0
Dallas 0
Houston 0
Honolulu 0
Miami 0
Reno 0
All input is guaranteed to be single-word followed by enter only. It may not match a city name, but there will be no spaces. This keeps your program simple as it lets you avoid using getline( ), which would be needed to deal with blanks between words.
Sales data is guaranteed good when input.
When I attempted to run my program, visual studios went crazy, and I've pulled out my hair trying to fix it. If someone could help give me some pointers on what I've done wrong, I would greatly appreciate it. Here is a copy of my program:
#include <iostream>
#include <string>
using namespace std;
int main()
{
//declare city and sales array
string city[8] = {" "};
int sales[8] = {0};
//declare variables
string cityName = " ";
int cityTotal = 0;
int salesAmt = 0;
int i = 0;
char another = ' ';
//init city array
city[0] = "Atlanta";
city[1] = "Buffalo";
city[2] = "Chicago";
city[3] = "Dallas";
city[4] = "Houston";
city[5] = "Honololu";
city[6] = "Miami";
city[7] = "Reno";
do
{
//input city name and if found input sales amount
cout << "Enter a City: Atlanta, Buffalo, Chicago, Dallas, Houston, Honololu, Miami, or Reno: ";
cin >> cityName;
for(i = 0; i <= 8; i++)
{
if(cityName == city[i])
{cout << "Enter sales amount: ";
cin >> salesAmt;
salesAmt += sales[i];}
else
{cout << "ERROR: CITY NOT AVAILIABLE" << endl;
cout << endl;}
//end if
}
//end for loop
//ask if another city
cout << "Enter another city?: ";
cin >> another;
} //end do loop
while(another == 'Y' || another == 'y');
{
for(i = 0; i <= 8; i++)
{
cout << "City: " << " " << "Sales: " << endl;
cout << city[i] << " " << sales[i] << endl;
}
//end for loop
} //end while loop
system("pause");
return 0;
} //end of main
A clear error here is the way you have used the index to access the arrays, you can't have the for loop reach 8, as the array's index is only up to 7. change your for loops to:
for(i = 0; i < 8; i++)
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
//declare city and sales array
string city[8] = {" "};
int sales[8] = {0};
//declare variables
string cityName ="";
int cityTotal = 0;
int salesAmt = 0;
int i = 0;
char another = ' ';
//init city array
city[0] = "Atlanta";
city[1] = "Buffalo";
city[2] = "Chicago";
city[3] = "Dallas";
city[4] = "Houston";
city[5] = "Honololu";
city[6] = "Miami";
city[7] = "Reno";
do
{
//input city name and if found input sales amount
cout << "Enter a City: Atlanta, Buffalo, Chicago, Dallas, Houston, Honololu, Miami, or Reno: ";
cin >> cityName;
for(i = 0; i < 8; i++)
{
if(cityName == city[i])
{
cout << "Enter sales amount: ";
cin >> salesAmt;
sales[i] += salesAmt;
} else if (i==7)
{
cout << "ERROR: CITY NOT AVAILIABLE" << endl;
}//end if
}//end for loop
//ask if another city
cout << "Enter another city?: ";
cin >> another;
} //end do loop
while(another == 'Y' || another == 'y');
{
for(i = 0; i < 8; i++)
{
cout << "City: " << " " << "Sales: " << endl;
cout << city[i] << " " << sales[i] << endl;
}
//end for loop
} //end while loop
system("pause");
return 0;
} //end of main
error was for(i = 0; i <= 8; i++) change with for(i = 0; i < 8; i++) and also second for.
Next error changed to sales[i] += salesAmt; and Not salesAmt +=sales[i];.
And your city name is case sensitive when you input city name!