Trouble Implementing Two Vectors MVS C++ - c++

Hello Stack Overflow users,
I have this program that i am trying to create for my collection of movies, and please forgive me for some of my mistakes and oversights since I AM NEW TO C++, but basically my program runs (yay) but when I chose any of the four options this error pops up:
Main Error
I want the first program option to display like this:
Akira 10.0
Blade Runner 10.0
Deadpool 8.8
BUT IT DOESN'T DO THAT it just looks like:
10.0
10.0
8.8
Example of my bad output
My output just displays all of the scores on new lines but no movie titles show up and if I try any of the last three options (highest/lowest/average) it just displays the same error: Same error as above
If you could give me any pointers (or a code example) as what I need to do to make the output appear as the bold one above, that would be amazing!
Again please forgive me for possible simple errors I am making since this is my first time working with vectors.
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
// Function Prototypes
void displayList(vector<string>,vector<double>);
void highestRating(vector<double>);
void lowestRating(vector<double>);
void averageRating(vector<double>);
// 1st Vector Defintion
vector<string> movies{ // inside this is a list of 48 strings containing movie names (Ex: "Akira", "Blade Runner" };
// 2nd Vector Definition
vector<double> ratings{ // Inside this is a list of 48 doubles that contain movie scores for each movie
and i wish for it to print out directly right of the movie title, then turn to the next line.
Examples of numbers inside this vector: 9.9, 10.0, 5.5, 7.5 };
// Main
int main()
{
cout << fixed << showpoint << setprecision(1);
// Variable Definitions
const int DISPLAY = 1, HIGHEST = 2, LOWEST = 3, AVG = 4;
int response;
cout << "-------Welcome to C++ Newbie's Movie Collection Database-------" << endl;
cout << "\nEnter 1 to display the whole collection" << "\nEnter 2 to display the 5 highest rated movies by me";
cout << "\nEnter 3 to display the lowest 5 rated movies by me" << "\nEnter 4 to display the average score of the movies in the collection along with some other math" << endl;
cin >> response;
// Menu
do
{
switch (response)
{
case(DISPLAY):
{
displayList(movies, ratings);
break;
}
case(HIGHEST):
{
highestRating(ratings);
break;
}
case(LOWEST):
{
lowestRating(ratings);
break;
}
case(AVG):
{
averageRating(ratings);
break;
}
default:
{
exit(0);
}
}
} while (response == 1 || response == 2 || response == 3 || response == 4);
return 0;
}
// Display List
void displayList(vector <string> movies, vector <double> ratings)
{
for (int val = 0; val <= movies.size(); ++val)
{
cout << movies[val] << "\t";
for (int rat = 0; rat <= ratings.size(); ++rat)
{
cout << ratings[rat] << endl;
}
}
}
// Display highest by me
void highestRating(vector<double> ratings)
{
double max = ratings[0];
for (int i = 0; i <= ratings.size(); i++)
{
if (ratings[i] >= max)
max = ratings[i];
}
cout << "\nThe highest rated movie is " << max << endl;
}
// Display Lowest by me
void lowestRating(vector<double> ratings)
{
double min = ratings[0];
for (int a = 0; a <= ratings.size(); a++)
{
if (ratings[a] <= min)
min = ratings[a];
}
cout << "\nThe lowest rated movie is" << min << endl;
}
// Average Score by me
void averageRating(vector<double> ratings)
{
double average;
double total = 0;
for (int x = 0; x <= ratings.size(); x++)
{
total += ratings[x];
}
average = total / ratings.size();
cout << "\nThe average is " << average << endl;
double forTheFunOfIt = fmod(average, 2.0);
cout << "\nThe Average divided by 2 is " << forTheFunOfIt << endl;
}

To address your first problem in displayList(), you are displaying a movie, and then looping to display all of the ratings. You probably need to display both within the same single loop. Also, if you do this then you need to make sure that both vectors have the exact same sizes to avoid attempting to access beyond the range of your vector, (it is probably best to use a std::map of movies and rating).
Having said that, for your code above maybe try changing displayList() to something like
// Display List
void displayList(vector <string> movies, vector <double> ratings)
{
for (int val = 0; val < movies.size(); val++)
{
cout << movies[val] << "\t" << ratings[val] << std::endl;
}
}
Note, you are not going to want to loop while val <= movies.size(), the indexes to your vector of (for example) 4 movies and 4 ratings will be 0-3, not 0-4. You will encounter an error indicating you are out of range.
Now for your next problem, you are looping in main() on the initial input from the user, but you are never updating the response variable from a user input. This will cause you to fall into an infinite loop! An easy fix for you will be to move cin >> response into the top of your do-while loop.
Moving onto the next couple issues, which is invalid output for your highest, lowest, and average. Again, you should not be looping while the index is less than or equal to the total size of the vector. Instead, you want less than only.
Lastly, you may want to consider passing your vectors as const references

Related

if, else if, else function isn't accurately displaying results

#include <iostream>
using namespace std;
// prototype functions
void DisplayResult(float MaxOrMin);
float FindMinimum(float Array[5]);
float FindMaximum(float Array[5]);
//Global Variables
float Array[5];
float MaxOrMin = 3;
float FindMin;
float FindMax;
//Main Function
int main()
{
cout << "Please enter 5 numbers: " << endl;
for (int i=0; i<5; i++)
{
cin >> Array[i]; // input for array
}
cout << "Please enter '0' for minimum or '9' for maximum:" << endl;
cin >> MaxOrMin; // input 0 or 9 for min or max
//Calling Functions
FindMinimum(Array);
FindMaximum(Array);
DisplayResult(MaxOrMin);
return 0;
}
//Function to find Minimum
float FindMinimum(float Array[5])
{
float FindMin = Array[0];
for (int y=1;y<5;y++)
{
if(Array[y] < FindMin)
FindMin = Array[y];
}
return FindMin;
}
//Function to find Maximum
float FindMaximum(float Array[5])
{
float FindMax = Array[0];
for (int x=1;x<5;x++)
{
if(Array[x] > FindMax)
FindMax = Array[x];
}
return FindMax;
}
This last part is my if, else if, else funtion:
//Function to display minimum or maximum result
void DisplayResult(float MaxOrMin)
{
if (MaxOrMin == 0)
cout << "Minimum is: " << FindMin << endl;
else if (MaxOrMin == 9)
cout << "Maximum is: " << FindMax << endl;
else
cout << "Invalid Input" << endl;
}
My project is to create a program using functions to take user input on a 5 float array. Then find the max and min and display whichever the user asks for.
Here is where my problem comes in. For both max(input 9) and min(input 0) I am getting "0". However any other input correctly returns my "Invalid Input" message.
I'm not getting any errors or warnings or errors at all on eclipse. My professor has told me that my problem was likely with my void function for displaying results. I am hoping someone could point me in the right direction here.
Apologies for my formatting and/or if this question is too basic for this site.
You misunderstand how local and global variables work. Your Find* functions shadow the globals with locals and thus they don't appear to do anything.
The problem is that your FindMinimum() (and the same with FindMaximum()) function compute the minimum (maximum) in a local variable and return it but you, in main() don't receive they in correct variables
So the computed value is lost.
I mean... instead of
FindMinimum(Array);
FindMaximum(Array);
you should write
FindMin = FindMinimum(Array);
FindMax = FindMaximum(Array);

Creating an array

write a program that let's the user enter 10 numbers into an array. The program should then display the largest number as and the smallest number stored in the array.
I am very confused on this question that was on a previous exam and will be on the final. Any help would be appreciated! This is what I had on the test and got 3/15 points, and the code was almost completely wrong but I can post what I had if necessary, thanks! For creating the array, i can at least get that started, so like this?
#include <iostream>
using namespace std;
int main()
{
int array(10); // the array with 10 numbers, which the user will enter
cout << "Please enter 10 numbers which will be stored in this array" << endl;
cin >> array;
int smallest=0; //accounting for int data type and the actual smallest number
int largest=0; //accounting for int data type and the actual largest number
//-both of these starting at 0 to show accurate results-
And then on my test, i started using for loops and it got messy from there on out, so my big problem here i think is how to actually compare/find the smallest and largest numbers, in the best way possible. I'm also just in computer science 1 at university so we keep it pretty simple, or i like to. We also know binary search and one other search method, if either of those would be a good way to use here to write code for doing this. Thanks!
Start by declaring an array correctly. int array(10) initializes a single integer variable named array to have the value 10. (Same as saying int array = 10)
You declare an array of 10 integers as follows:
int array[10];
Anyway, two simple loops and you are done.
int array[10];
cout << "Enter 10 numbers" << endl;
for (int x = 0; x < 10; x++)
{
cin >> array[x];
}
int smallest=array[0];
int largest=array[0];
for (int x = 1; x < 10; x++)
{
if (array[x] < smallest)
{
smallest = array[x];
}
else if (array[x] > largest)
{
largest = array[x];
}
}
cout << "Largest: " << largest << endl;
cout << "Smallest: " << smallest << endl;
You can actually combine the two for loops above into a single loop. That's an exercise in an optimization that I'll leave up to you.
In this case, you don't actually have to do a binary search, or search the array. Since you will be receiving the input directly from the user, you can keep track of minimum and maximum as you encounter them, as show below. You know the first number you receive will be both the min and max. Then you compare the next number you get with those ones. If it's bigger or smaller, you store it as the max or min respectively. And then so on. I included code to store the number in an array, to check errors and to output the array back to the user, but that's probably not necessary on an exam due to the limited time. I included it as a little bit of extra info for you.
#include <cctype> // required for isdigit, error checking
#include <cstdlib> // required for atoi, convert text to an int
#include <iostream> // required for cout, cin, user input and output
#include <string> // required for string type, easier manipulation of text
int main()
{
// The number of numbers we need from the user.
int maxNumbers = 10;
// A variable to store the user's input before we can check for errors
std::string userInput;
// An array to store the user's input
int userNumbers[maxNumbers];
// store the largest and smallest number
int max, min;
// Counter variables, i is used for the two main loops in the program,
// while j is used in a loop for error checking
int i;
unsigned int j;
// Prompt the user for input.
std::cout << "Please enter " << maxNumbers << " numbers: " << std::endl;
// i is used to keep track of the number of valid numbers inputted
i = 0;
// Keep waiting for user input until the user enters the maxNumber valid
// numbers
while (i < maxNumbers)
{
// Get the user's next number, store it as string so we can check
// for errors
std::cout << "Number " << (i+1) << ": ";
std::cin >> userInput;
// This variable is used to keep track of whether or not there is
// an error in the user's input.
bool validInput = true;
// Loop through the entire inputted string and check they are all
// valid digits
for (j = 0; j < userInput.length(); j++)
{
// Check if the character at pos j in the input is a digit.
if (!isdigit(userInput.at(j)))
{
// This is not a digit, we found an error so we can stop looping
validInput = false;
break;
}
}
// If it is a valid number, store it in the array of
// numbers inputted by the user.
if (validInput)
{
// We store this number in the array, and increment the number
// of valid numbers we got.
userNumbers[i] = atoi(userInput.c_str());
// If this is the first valid input we got, then we have nothing
// to compare to yet, so store the input as the max and min
if (i == 0)
{
min = userNumbers[i];
max = userNumbers[i];
}
else {
// Is this the smallest int we have seen?
if (min < userNumbers[i])
{
min = userNumbers[i];
}
// Is this the largest int we have seen?
if (max < userNumbers[i])
{
max = userNumbers[i];
}
}
i++;
}
else
{
// This is not a valid number, inform the user of their error.
std::cout << "Invalid number, please enter a valid number." << std::endl;
}
}
// Output the user's numbers to them.
std::cout << "Your numbers are: " << userNumbers[0];
for (i = 1; i < maxNumbers; i++)
{
std::cout << "," << userNumbers[i];
}
std::cout << "." << std::endl;
// Output the min and max
std::cout << "Smallest int: " << min << std::endl;
std::cout << "Largest int: " << max << std::endl;
return 0;
}

Gross Pay using Arrays (C++)

I am writing a code to calculate the gross pay of seven employees using arrays. Here is what I have so far
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
//Set all constants and variables
const int SIZE = 7; //Size of all arrays
int emID[SIZE] = {1234, 4563, 8765, 4568, 9867, 9235, 7684};
double Hours[SIZE],
Rate[SIZE],
Gross[SIZE];
int index;
Gross[index] = (Hours[index] * Rate[index]);
//Explain Program
cout << "This program calculates an employees gross pay\n";
for (Hours[index];index <= 6; index++)
{
cout << "How many hours did employee " << emID[index] << " work?\n";
cin >> Hours[index];
}
for (Rate[index]; index <= 6; index++)
{
cout << "Enter the pay rate for " << emID[index] << endl;
cin >> Rate[index];
}
for (Gross[index]; index <=6 ; index++)
{
cout << "The gross pay for " << emID[index] << " is " << Hours[index] * Rate[index];
}
}
Unfortunately the program terminates after the first "for" loop. Any suggestions?
There seem to be a few mistakes in your code, which I'm pointing out below.
index is unitialised, and the way you've used it results in Undefined Behavior. I think you meant to initialise to to 0.
You should reset the value of index to 0 between for loops. Currently you would iterate in the first for loop. After that, since index will be > 6, your code will not execute the other two for loops.
Your first term in the for loop declarations is wrong. I think you meant to declare index = 0 there. If not, you should leave it empty.
The line near the beginning where you calculate Gross[index] is wrong and redundant.

Simple C++ input files and if statements

I wrote the code and it works except the total is wrong. It is supposed to multiply the distanceRate by the rate and add each cost to make the total, but it's not doing that. Any help would be appreciated.
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
//Declare Variables
ifstream inFile;
double packageWeight;
double distance;
double totalCharge = 0;
double rate;
double distanceRate;
int customerNumber;
double shippingCharge;
int packageCount = 0;
inFile.open("shipping.txt");
if(inFile)
{
cout << "Customer Package Shipping" << endl;
cout << "Number Weight Distance" << endl;
while(!inFile.eof())
{
inFile >> customerNumber;
inFile >> packageWeight;
inFile >> distance;
if(0 < packageWeight <= 2)
rate = 1.10;
else if(2 < packageWeight <=6)
rate = 2.20;
else if(6 < packageWeight <= 10)
rate = 3.70;
else if(10 < packageWeight <=20)
rate = 4.80;
else
cout << "Invalid package weight" << endl;
if( 0 < distance <= 500)
distanceRate = 1;
else if( 500 < distance <= 1000)
distanceRate = 2;
else if(1000 < distance <= 1500)
distanceRate = 3;
else if(1500 < distance <= 2000)
distanceRate = 4;
else
cout << "Invalid distance" << endl;
packageCount += customerNumber;
shippingCharge = rate * distanceRate;
totalCharge += shippingCharge;
cout << fixed << setprecision(2) << showpoint;
cout << setw(2) << customerNumber
<< right << setw(14) << packageWeight
<< setw(13) << distance
<< endl;
} //End of while loop
cout << "\nPackage shipped : " << packageCount << endl;
cout << "Total Charge : $" << totalCharge << endl;
inFile.close();
}
else
{
cout << "Could not open file" << endl;
}
system("pause");
return 0;
}
Some issues that I see in the snippet you gave me are as follows:
As pointed out by billz in a comment, your if statements are invalid. The statement if( 0 < distance <= 500) is not doing what you expect, it evaluates from left to right, so you have 0 < distance (lets say that evaluates to true) so then you have true <= 1000 which isn't going to give the results that you think it will. This actually needs to be broken apart into two separate comparisons like distance > 0 && distance < 500.
As I noted in my comment, you're adding the customer number to the package count, this will most likely always give a wrong value for package count. If your customer numbers are 1, 2, 3, 4 then you claim the package count is 10 when it's actually only 4 (forgive me if I misunderstood the purpose of this field).
You have no default value for distanceRate but you still use it in an operation (possibly uninitialized) which will give unexpected results (as you are seeing). In your else, you should actually give it a dummy value that way you guarantee that it will always be set. You also do reset it, so if it gets set to 4, and then next distance fails the tests and enters the else, you have another calculation on the variable as 4 instead of it's default value. You should initialize any variable that you plan to use unless you have explicit reason not to give it a value at initialization, and anytime you use a variable in a loop you should reset it's value at the start of the loop.
Additional Note (EDIT)
I wouldn't recommend using system("pause"); as it does a lot more behind the scenes than you would want in a simple pause, a better approach I've seen used is:
#include <iostream>
#include <conio.h>
using namespace std;
int main() {
cout << "Press any key to continue!";
_getch();
cout << "Finished";
return 0;
}
EDIT 2
If statments can contain a single line or a code block to execute.
Single line:
if (someValueIsTrue)
executeThisFunction();
Code block:
if (someValueIsTrue) {
executeThisFunction();
alsoThisFunction();
}
Anytime you need to execute more than one statement in an if/else/while/for/do...while/etc... you'll need a code block. I imagine (based on your explanation) that you did:
if (blah)
// ....
else
distanceRate = 0;
cout << "Invalid Distance";
And the compiler only sees that you have the distanceRate = 0 nested in the loop, the cout statement is actually not part of the else but part of the previous block of code. You need to use a code block here.
!inFile.eof() // incorrect
inFile.good() // correct
read on eof() it doesn't do what you might think it does.
if( 0 < distance <= 500) // all the if statements are incorrect
if(distance>0 && distance<=500) // correct
The way you wrote the if condition, it does not do what you think it does.

I'm getting a weird error for a program that seems like it should "just work."

I present to you all a program I'm working on for my college programming course. I still have a little ways to go before it completely meets my assignment's requirements, but I've gotten a basic draft of the program error-free (supposedly) and it appears to run… but then it suddenly kicks me into Xcode's debugger and gives me:
Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff95c1e5f5)
Here's the command line output, up until it kicks me out:
-----------------------
Quarterly_sales_taxator
-----------------------
How many company divisions will we be dealing with? 2
Am I correct in assuming that there are 4 sales quarters? yes
Please enter the sales Company Division #1 brought in for Sales Quarter #1 20
(lldb)
Here's my code:
//
// quarterly_sales_taxator.cpp
// Ch. 7 program #7
//
// Created by John Doe on 11/27/12.
//
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cctype>
using namespace std;
void read_company_divisions_and_sales_quarters(double **, int, int);
//void write_company_divisions_and_sales_quarters_to_array(double **, int, int); // This will be used later on to read data from a file.
void display_quarterly_sales_array(double **, int, int);
string temp; // A global temporary placeholder variable; I use this several times.
int main()
{
int COMPANY_DIVISIONS,
SALES_QUARTERS = 4;
double **quarterly_sales_form;
cout << "\n\n-----------------------\nQuarterly_sales_taxator\n-----------------------\n\n";
cout << "\nHow many company divisions will we be dealing with? ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
while (COMPANY_DIVISIONS < 1 || isdigit(COMPANY_DIVISIONS == false))
{
cout << "\n\n------"
<< "\nError:"
<< "\n------"
<< "\n\nYou have entered an invalid choice."
<< "\nPlease type a number greater than zero. ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
}
cout << "\n\nAm I correct in assuming that there are 4 sales quarters? ";
getline(cin, temp);
// Convert to uppercase.
for (int count = 0; count < temp.length(); count ++)
{
temp[count] = toupper(temp[count]);
}
if (temp == "NO" || temp == "NOPE" || temp == "INCORRECT" || temp == "YOU ARE NOT" || temp == "YOU ARE INCORRECT" || temp == "NEGATIVE" || temp == "NEGATORY")
{
cout << "\nOk, then how many sales quarters are we dealing with? ";
getline(cin, temp);
stringstream(temp)>>SALES_QUARTERS;
}
cout << endl << endl;
// This sets up the 2d array.
quarterly_sales_form = new double *[COMPANY_DIVISIONS];
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
read_company_divisions_and_sales_quarters(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// write_company_divisions_and_sales_quarters_to_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS); // I'll add this feature later.
cout << "\n\nHere's what you entered:\n\n";
display_quarterly_sales_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// Since we used a series of pointers, we need to free the allocated space back up.
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ delete[] quarterly_sales_form[COMPANY_DIVISIONS]; }
delete[] quarterly_sales_form;
return 0;
}
/*############################################
# read_company_divisions_and_sales_quarters #
############################################*/
void read_company_divisions_and_sales_quarters(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < QUARTERS; count++)
{
for (int index = 0; index < DIVISIONS; index++)
{
cout << "\nPlease enter the sales Company Division #" << count+1 << " brought in for Sales Quarter #" << index+1 << " ";
getline(cin, temp);
stringstream(temp) >> array[count][index];
}
}
}
/*################################
# display_quarterly_sales_array #
#################################*/
void display_quarterly_sales_array(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < DIVISIONS; count++)
{
cout << "\nCompany division #" << count+1 << ":\n";
for (int index = 0; index < QUARTERS; index++)
{ cout << array[count][index] << ", "; }
}
}
Can some kind soul please tell me what I'm doing wrong?
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
In this line, COMPANY_DIVISIONS should be count.
In addition to what Dan Hulme said, it seems this line
stringstream(temp) >> array[count][index];
should really be
std::istringstream(temp) >> std::skipws >> array[index][count];
In addition to using std::istringstream rather than std::stringstream and making sure that an lvalue is at hand, which isn't strictly needed until the type read becomes more interesting, this also reverses the indices: index runs over COMPANY_DIVISIONS and count over SALES_QUARTERS.
The real question is, of course: Who hands out assignments like this? Pointer manipulations and allocations are best left to low-level library writers. This is C++ not C: we can and should use abstractions. Getting this code exception safe is a major challenge and there is no point in teaching people how to write broken (e.g. exception unsafe) code.