while loop to error check c++? - c++

Can someone please look at this code and help me figure out what's wrong?
#include <iostream>
#include <vector>
using namespace std;
int numExercise;
cout << "Enter num exercises: ";
cin >> numExercise;
vector <float> weight;
float sumWeight = 0;
while(sumWeight != 1)
{
// Loop to assign a weighted value to each exercise.
for ( int i = 0; i < numExercise; i++ )
{
float weightEntered;
cout << "\n Assignment " << i + 1 << " : ";
cin >> weightEntered;
//Divide percentage by 100 to get decimals.
weightEntered /= 100;
//Send the data back to the vector.
weight.push_back( weightEntered );
}
// Loop to error check if the total weights isn't 100.
for ( int i = 0; i < numExercise; i++ )
{
sumWeight += weight[i];
}
cout << sumWeight << endl;
sumWeight = 0;
//if ( sumWeight != 1 )
cout << "\n\t\tError, total weights should be 100" << endl;
}
So in this code I'm entering a certain amount of assignments and the weights per assignment have to be over 100%... for example enter 3 assignments and each weight is 30, 30, 40. After the weight is entered the code divides each weight by 100 to get decimal values (I'm using that in the rest of my code to calculate something else).
The issue is that I'm trying to make sure that whatever the user enters add up to 100 otherwise they have to enter the numbers again. When I run this loop and enter the wrong numbers it asks me to enter them again but it doesn't go through the sum of the weights entered the second time, so the number displayed is still the first sum. What am I doing wrong??

You are using vector to store the weights,
Let say for three assignments, you entered 30,30,30. Now vector becomes { 30,30,30 } and you are summing over this vector from 0 to 2 index.
In next time, you entered 20,20,40. Now vector becomes {30,30,30,20,20,40} and you are summing over this vector again from 0 to 2 index.
You can solve your problem by using insert rather than push_back

Related

How to receive input with whitespaces that are then stored into a vector?

I am new to C++, but this picture here is the goal of my program.
This is what I need my input/output to look like:
--- INPUT ---
The first line of standard input contains an integer 1 ≤ C ≤ 50, the number of test cases.
C data sets follow. Each data set begins with an integer, N, the number of people in the class (1 ≤ N ≤ 1000).
N integers follow, separated by spaces or newlines, each giving the final grade (an integer between 0 and 100) of a student in the class.
--- OUTPUT ---
For each case you are to output a line giving the percentage of students whose grade is above average, rounded to exactly 3 decimal places.
This is the code that I currently have:
#include <iomanip>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using std::vector;
void aboveAverage(int testCases) {
// initialize number of students for vector size
int numOfStudents;
// initialize a vector to hold grades
vector<int> grades;
// for # of testCases, recieve # of students per test case
for(int i = 0; i < testCases; i++) {
std::cout << "Num of Students: ";
std::cin >> numOfStudents;
// per test case, recieve grade per student and push into vector
for(int j = 0; j < numOfStudents; j++) {
int grade1;
std::string grade;
// debug statement
std::cout << "Enter grades: ";
std::getline(std::cin, grade);
grade = int(grade1);
grades.push_back(grade1);
}
}
// sum the vector array and intitialize above average threshold
int sum = std::accumulate(grades.begin(), grades.end(), 0);
// debug statement
std::cout << "Sum = " << sum << std::endl;
int threshold = sum / numOfStudents;
// initialize a counter and based on threshold get the # of elements that
// meet that criteria
int counter = 0;
for(int j = 0; j < numOfStudents; j++) {
// if the grade is larger than the threshold, add to counter
if(grades[j] > threshold) {
counter += 1;
}
}
// get the percentage of those above average and print it out
float percentage = (counter / numOfStudents) * 10;
std::cout << std::setprecision(3) << std::fixed << percentage << std::endl;
}
int main() {
int testCases;
// debug statement
std::cout << "# of Test Cases: ";
std::cin >> testCases;
aboveAverage(testCases);
return 0;
}
The code as a whole runs "fine", I guess you could say. Just no errors in the compiler that yell at me at least. I just cannot, for the life of me, figure out how to set it up exactly like it should for the input. I think I complicated my life with the vector, although it seems easier to me this way. I think I'm close. Hopefully I am!

Trouble Implementing Two Vectors MVS 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

Array prints out wrong numbers

I'm new to C++ and I have to make a program that lets the user enter a specified number of test scores and calculate the average, highest, and lowest scores. (It doesn't have to check if values are between 1 and 100.) For some reason, when it goes to print out the average score and sum of the scores, it just prints out random exponential numbers that are never the same. I haven't gotten to printing out the lowest and highest scores yet since I'm not sure if I'm even doing the average right. Again, I'm new to C++ so I'm sure I messed something up. Here's the code:
#include <iostream>
using namespace std;
int loopLimit = 0; //number of scores or how many times it will loop
double *testScores = {0}; //array scores are stored in
int main () {
cout << "How many test scores are you entering?" << endl;
cin >> loopLimit;
testScores = new double[loopLimit]; //changes array to needed size
for (int i = 0; i < loopLimit; i++) {
cout << "Enter test score #" << (i + 1) << endl;
cin >> *testScores;
}
double sum = 0.0;
double average = 0.0;
//double max = 0.0; //making these functions later
//double min = 0.0;
sum += testScores[loopLimit];
average = sum / loopLimit;
//Sum is here for testing purposes at the moment
cout << "Sum = " << sum << " Average = " << average << endl;
return 0;
}
Example output 1:
How many test scores are you entering?
3
Enter test score #1
100
Enter test score #2
100
Enter test score #3
100
Sum = 8.29874e-310 Average = 2.76625e-310
Example output 2:
How many test scores are you entering?
3
Enter test score #1
100
Enter test score #2
100
Enter test score #3
100
Sum = 8.94176e-310 Average = 2.98059e-310
Expected output:
How many test scores are you entering?
3
Enter test score #1
100
Enter test score #2
100
Enter test score #3
100
Sum = 300.0 Average = 100.0
I've been at this all week, and I honestly got nothing at this point.
OK, let's go over your code.
#include <iostream>
using namespace std;
Why are you importing all identifiers in std:: here? using namespace std; is not recommended.
int loopLimit = 0; //number of scores or how many times it will loop
double *testScores = {0}; //array scores are stored in
Bad: You should avoid global variables unless they're absolutely necessary. 99.9% of the time they're not. These could easily be local variables in main.
testScores is not an array, it's a pointer. Initializing it with {0} is just a weird way of writing testScores = nullptr;.
int main () {
cout << "How many test scores are you entering?" << endl;
cin >> loopLimit;
testScores = new double[loopLimit]; //changes array to needed size
You're using manual memory management here. Not technically wrong, but it would be much easier and less error prone to use a std::vector instead.
for (int i = 0; i < loopLimit; i++) {
cout << "Enter test score #" << (i + 1) << endl;
cin >> *testScores;
This line stores every input in *testScores, i.e. the location pointed to by testScores, which corresponds to the first index of the array allocated by new above. This means only testScores[0] is initialized (ending up containing the last number the user input), every other index is uninitialized.
You should use cin >> testScores[i] instead.
}
double sum = 0.0;
double average = 0.0;
//double max = 0.0; //making these functions later
//double min = 0.0;
sum += testScores[loopLimit];
This is an invalid memory access. As testScores points to a dynamic array of size loopLimit, the valid array indices go from 0 to loopLimit-1. Therefore testScores[loopLimit] accesses memory past the bounds of the array.
Also, it's just one element you're adding here. Even if this were a valid array index, this could would still make no sense. You should loop over all array elements here (like your for loop above), or just do this part of the calculation in your other loop. In fact, there's no need to store all numbers in memory if all you're interested in is their sum (which you can compute directly as you're reading the input).
average = sum / loopLimit;
average is computed from sum, which has a garbage value, so it's garbage too.
//Sum is here for testing purposes at the moment
cout << "Sum = " << sum << " Average = " << average << endl;
... and this is why you're getting garbage output.
return 0;
Here you're leaking the memory allocated with new. This is not really a problem in this case because your program is about to exit anyway, but in general you want delete[] testScores; here (unless you use a std::vector, which takes care of cleaning up for you).
}
A couple of things, first the line
cin >> *testScores;
is not storing the test scores in an array (I think this is what you want to do) instead at every iteration the new test score is being stored in the first element i.e testScores[0], rewriting the old value.
Next,
The line
sum += testScores[loopLimit];
looks outside the array. This means that you are looking at a random place in memory which probably has junk in it. That explains why you are seeing random numbers outputted.
Try to fix those two issues. If you don't need to save the test scores you can away keep a running sum of them, that would eliminate the need to store everything in an array.
I don't know why you want to write such a messed up code for just calculating average.But here's my approach.
Since you entered loopLimit value as 3.So according to your code,sum will contain have the value of sum[3].That is a garbage value.Since indexing starts with 0 and not 1.So your sum will have a garbage value and that is the reason why you are getting such incorrect value.I have modified your code and it works fine for me.
int loopLimit;
cout << "How many test scores are you entering?" << endl;
cin >> loopLimit;
double scores[loopLimit];
double sum=0.0;
for (int i = 0; i < loopLimit; i++)
{
cout << "Enter test score #" << (i + 1) << endl;
cin >> scores[i];
sum+=scores[i];
}
double avg=sum/loopLimit;
cout << "Sum = " << sum << " Average = " << avg << endl;
return 0;
Try avoiding using pointers during the early stage of programming as it can really mess up with your brain and can create problems.Try to go for a simple approach.
The possible issue is that you're doing this
double* testScores = {0};
which will initialize it to nullptr, potentially letting you read and write garbage data. What you should use instead is probably a dynamic resizing array such as
std::vector<double> testScores;
and to add a score to the list
double inScore = 0;
std::cin >> inScore;
testScores.push_back(inScore); // This adds to the list of scores.
#include <iostream>
using namespace std;
int loopLimit = 0; //number of scores or how many times it will loop
double *testScores = {0}; //array scores are stored in
int main () {
double sum = 0.0;
double average = 0.0;
cout << "How many test scores are you entering?" << endl;
cin >> loopLimit;
testScores = new double[loopLimit]; //changes array to needed size
for (int i = 0; i < loopLimit; i++) {
cout << "Enter test score #" << (i + 1) << endl;
cin >> testScores[i];
sum += testScores[i];
}
average = sum / loopLimit;
cout << "Sum = " << sum << " Average = " << average << endl;
delete [] testScores;
return 0;
}
*melpomene is right...that pointer "testScores" wont increment through your for loop so the array occupies garbage also put sum += testScores[i] in the loop to sum your input.

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;
}

Need help in basic C++ regarding how to properly loop through part and finding smallest value

Hi I'm needing some help. I'm in a intro to programming class and we are using c++. I am hoping someone can help me with an assignment that was due yesterday (I understand not to expect miracle responses but a girl can always try).
I'm having two problems that I know of. The first is regarding the smallest value.
The big one is in trying to make it loop for requirements of three times but not lose out on my total count. I cannot use arrays or anything I haven't learned yet which is why I've posted this. I've seen similar problems and questions but they have ended up with answers too complex for current progress in class. So here is the problems instructions:
Instructions
1) Write a program to find the average value, the largest value, and the smallest value of a set of numbers supplied as input from the keyboard. The number of values in the data set must be in the range 0 to 20, inclusive. The user will first enter the number of values in the data set(use variable int Number). Give the user 3 attempts at entering Number in the range given. If the value for Number entered is out of this range, write an error message but continue. If the user does not enter a valid value for Number within the 3 attempts print an error message and terminate the program.
2) Format only the output for the Average value to 3 decimal places when printed.
3) The values in the data set entered as input can be any value positive, negative, or zero.
4) Make the program output readable(see the example below). (Note: that you will notprint out the input values that were entered in this program like you normally are required to do. This is because we have not covered the “tool” needed to do so yet in our studies).
Below will be the output from the execution of your program:
(using these values in order for the data set --> 19.0 53.4 704.0 -15.2 0 100.0)
The largest number: 704
The smallest number: -15.2
The average of the 6 numbers entered: 143.533
yourName L4p2XX.cpp
Lab#4 prob 2 XX-XX-12
Here is my poor excuse at the solution:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double Number = 0, minValue, maxValue, average, total = 0;
int ct = 0, numCount;
cout << "How many numbers would you like to enter? ";
cin >> numCount;
for(ct = 1; ct <= numCount; ct += 1)
{
cout << "Enter Value from 0 to 20, inclusive: ";
cin >> Number;
if(Number > 20|| Number < 0)
for(int errorCt = 1; errorCt <= 4; errorCt += 1)
{
if(errorCt == 4)
{
cout << "You have had 3 attempts to enter a valid" <<
"number. \nPlease try this program again when you" <<
"are able to follow directions.";
cout <<"\nLBn\n"<<"L4P2LB.cpp\n"<<"11-05-12\n";
return 0;
}
cout << Number << "is not within range.\n" <<
"Please enter a number from 0 to 20: ";
cin >> Number;
} //end for loop
total += Number;
if(maxValue <= Number)
maxValue = Number;
if(Number <= minValue)
minValue = Number;
} //end for loop
cout << "The smallest number entered was " << minValue << endl;
cout << "The largest number you entered was " << maxValue << endl;
average = total/numCount;
cout << setprecision(3) << fixed << showpoint << "You entered " <<
numCount << " numbers. The average of these is " << average;
//Program ID
cout <<"\n" << "L4P2LB.cpp\n" << "11-05-12\n";
system ("pause");
return 0;
} // End main
Thank you in advance to anyone who can steer me in the right direction. Not looking for anyone to do my work I just need help in direction if nothing else or any suggestions as to what to do. Thanks again. Lynda
Also I need somehow to pause after the third time and exit properly. If I put the second pause in it won't work so am I missing something obvious there too!
The first problem I see is that you didn't initialize a couple of variables.
You should either initialize both minValue and maxValue variables with something which will overwritten in every case in the first loop (typically "positive/negative infinity", as provided by <limits>), or just set both to Number in the first iteration, regardless of their current value. So I'd suggest to fix this by replacing
if(maxValue <= Number)
maxValue = Number;
if(Number <= minValue)
minValue = Number;
with
if(maxValue <= Number || ct == 1)
maxValue = Number;
if(Number <= minValue || ct == 1)
minValue = Number;
as ct == 1 will be true in the first iteration.
That said, you check the 0..20 range condition on the wrong variable. You check it on the Number variable, but you should check the numCount variable. But you also didn't respect the requirement that the variable to store the "number of numbers" should be Number, so you did check the correct variable, but used the wrong to read the input into. This should fix this issue (I changed the variable name in the cin >>... line + moved the check outside your main loop):
cout << "How many numbers would you like to enter? ";
cin >> Number;
if(Number > 20|| Number < 0)
{
for(int errorCt = 1; errorCt <= 4; errorCt += 1)
...
if(errorCt == 4)
{
cout << "You have had 3 attempts to enter a valid" <<
"number. \nPlease try this program again when you" <<
"are able to follow directions.";
cout <<"\nLBn\n"<<"L4P2LB.cpp\n"<<"11-05-12\n";
return 0;
}
cout << Number << "is not within range.\n" <<
"Please enter a number from 0 to 20: ";
cin >> Number;
} //end for loop
}
for(ct = 1; ct <= Number; ct += 1)
{
...
}
...