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.
Related
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!
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
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;
}
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.
I'm really confused. I have to make this lab for a class and I can't seem to have the search only display one result but all of the months of the year. I also can't seem to figure out why its not displaying the TotalRainfall when I input 0 into the month of the year.
Thank you.
#include <iostream>
#include <fstream>
const int MaxSize = 12; //How many weather lines will be available.
using namespace std;
struct WeatherInformation
{
int Month; //Months of the year
float TotalMonthsRainfall; //Total amount of rainfall
float HighTemp; //The Highest temperature of the month.
float LowTemp; //The Lowest temperature of the month.
float AverageTemp; //The Average temperature of the month.
};
WeatherInformation WeatherArray[MaxSize]; //Declaring a month array of MaxSize
void ReadFile(ifstream& MyinFile, WeatherInformation WeatherArray[]);
void WeatherMonthSearch (WeatherInformation WeatherArray[]);
int main()
{
float TotalRainfall = 0;
int count = 1; //Counts how many times the for loop goes.
int MonthOfWeather; //User input of the month.
char ProgramRedo; //User input if they want to reuse the program.
char exit_char; //User input to exit the program.
ifstream MyinFile; //Variable that uses file.
ReadFile (MyinFile, WeatherArray); //Call ReadFile Function
WeatherMonthSearch (WeatherArray); //Call WeatherMonthSearch Function
MyinFile.close(); //Closes file.
}
//Brett Holmes
//4/30/2013
//PreCondition:You need a file labeled weather.dat
//PostCondition: It puts the file variables into an array.
void ReadFile(ifstream& MyinFile, WeatherInformation WeatherArray[])
{
float TotalRainfall = 0;
char exit_char;
int count = 0;
int Month = 0;
cout << "Your Weather Machine" << endl << endl;
MyinFile.open("weather.dat");
if (!MyinFile)
{ //no
cout << "Can't open input file." << endl; //Tests the right file.
char exit_char; //End Program
cout << "Press any key to exit" << endl;
cin >> exit_char;
}
for(count = 1; count < MaxSize; count++) //Puts the file variables in the array.
{
WeatherArray[count].Month = WeatherArray[count].Month + 1;
MyinFile >> WeatherArray[count].TotalMonthsRainfall;
MyinFile >> WeatherArray[count].HighTemp;
MyinFile >> WeatherArray[count].LowTemp;
(WeatherArray[count].AverageTemp = ((WeatherArray[count].HighTemp + WeatherArray[count].LowTemp)/2));
(TotalRainfall = TotalRainfall + WeatherArray[count].TotalMonthsRainfall);
}
}
//Brett Holmes
//4/30/13
//PreCondition:You need to have the months already put into an array in a struct.
//PostCondition:Outputs the rainfall stats the user puts in then asks to run again.
//Outputs a error message if they type in the month wrong.
void WeatherMonthSearch (WeatherInformation WeatherArray[])
{
float TotalRainfall;
int months;
int MonthOfWeather;
char ProgramRedo;
do
{
bool MonthFound = false;
cout << "Please input the number of the Month. Ex. 1=Jan. 2=Feb. etc \n\n";
cin >> MonthOfWeather;
for(int i = 1; i <= MaxSize; i++)
{
months = WeatherArray[i].Month;
if(months == MonthOfWeather ) //Finds the artist and outputs the results
{
cout << "\nTotal Months Rainfall: " << WeatherArray[i].TotalMonthsRainfall << " \n";
cout << "Highest Temperature: " << WeatherArray[i].HighTemp << " \n";
cout << "Lowest Temperature: " << WeatherArray[i].LowTemp << " \n";
cout << "Average Temperature: " << WeatherArray[i].AverageTemp << " \n";
MonthOfWeather = true;
}
}
if(MonthOfWeather == 0)
{
cout << "The total rainfall for the year is: " << TotalRainfall << ".";
}
if(MonthFound == false)
{
cout << "\nMonth Number error. Month not found. Try again.\n\n";
MonthOfWeather = false;
}
cout << "Would you like to look up another month of weather?\n";
cout << "Enter a 'Y' if yes and 'N' if no.\n";
cin >> ProgramRedo;
}while(ProgramRedo == 'Y');
}
Several obvious problems:
Arrays in C++ is 0-based, so your for loop is off-by-one. In your search function, for(int i = 1; i <= MaxSize; i++) should be for(int i = 0; i < MaxSize; i++). Similarly, in your read function, for(count = 1; count < MaxSize; count++) should be for(count = 0; count < MaxSize; count++) (If you want to skip index 0 because you are using it as a signal value, then you should set MaxSize to 13 and have the loop start at 1.)
Why are you assigning a boolean to MonthOfWeather? Do you mean MonthFound?
You read function is not setting the months correctly. WeatherArray[count].Month = WeatherArray[count].Month + 1; should be WeatherArray[count].Month = count; if you are using a 1-based loop or WeatherArray[count].Month = count + 1; if the loop is 0-based.
You calculated your total rainfall in the read function, but the result is stored in a local variable so it's lost when the read is done. Either make TotalRainfall a global variable or do your calculations in your search function.
There are a lot of redundant variable definitions: for example, your weather data array is a global so there is no reason to actually pass it around; exit_char is declared twice in your read function; the first five lines of your main() declared variables that you never used.
Also, your read function does not actually exit the program on failure - it even still attempts to read from the stream and then call your search function! If error-checking is a requirement, you should either have the read function return a boolean and check that the read function succeeded before calling your search function, or simply call std::exit after that cin >> exit_char;.
So, one problem you have is that you have local variables that appear in multiple places, but appears like you expect them to actually contain the same information.
For example, I see three different TotalRainFall. One in main, which is just there, not used for anything, one in ReadFile which is calculated, and one in WeatherMonthSearch, which is not set to anything.
I suspect you want all three of these to actually do something. One way to achieve that would be to remove the local ones in ReadFile and WeatherMonthSearch, and instead pass in the one from main (as a reference into ReadFile).
There's also a few places where you use variables without initializing them. Make it a habit to initialize EVERYTHING and EVERYWHERE!
Enable warnings in your compiler - if you have any form or reasonably new compiler (gcc or MS Visual Studio of recent vintage), it should tell you at least some of these things.