Does this function access and analyze an array properly? - c++

I working on an assignment for my introduction to programming class which is meant to perform operations on an array of grades. Here are the details:
Usinging the following parallel arrays:
const int NUM_GRADES =5;
string Students[NUM_STUDENTS] = {"Tom","Jane","Jo"};
int grades[NUM_STUDENTS][NUM_GRADES] ={{78,98,88,99,77},
{62,99,94,85,93},
{73,82,88,85,78}};
Write a function called displayNumStudentsAtLeastBForSelectedAssignment that takes the student and grade arrays as parameters, allows the user to select a valid assignment and locates and displays the number of the student with at least a grade >= 80 for that assignment in the format in the sample run below.
Here is the code I have written for this function. I am wondering if my logic makes sense as I was working on this all night and have just found a potential solution
//Displays the number of students with at least a B (>=80)
int DisplayNumStudentsAtLeastBForSelectedAssignment(string Students[NUM_STUDENTS], int grades[NUM_STUDENTS][NUM_GRADES])
{
std::cout << "Number of students with atleast a B: " << endl;
std::cout << "Please enter in an assignment number: ";
int assignmentNum;
std::cin >> assignmentNum;
getValidAssignmentNumber(assignmentNum);
int total =0;
for (int x = 0; x < NUM_STUDENTS; x++)
{
if (grades[x][assignmentNum-1]>= 80)
total = total + 1;
}
std::cout << "Number of students with at least B on assignment " << assignmentNum << ": " << total << endl;
}
The function seems to be working properly. Just curious if there is a more efficient way of doing it. Thank you all for the help in advance.

Related

Transversing an Array of structs error in C++

Current code:
const int MAX_CODENAME = 25;
const int MAX_SPOTS = 5;
struct Team {
string TeamName[MAX_CODENAME];
short int totalLeagueGames;
short int leagueWins;
short int leagueLoses;
};
//GLOBAL VARIABLES:
Team league[MAX_SPOTS];
void addTeams(){
int i = 0; //first loop
int j; //second loop
while(i < MAX_SPOTS){
cout << "****** ADD TEAMS ******" << endl;
cout << "Enter the teams name " << endl;
scanf("%s", league[i].TeamName) ;
}
void searchTeam(){
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
for(int i = 0; i < MAX_SPOTS; i++){
if(decider == league[i].TeamName){
cout << endl;
cout << league[i].TeamName << endl;
break;
}else{
cout << "Searching...." << endl;
}
}
}
I really dont know why its not working but I have included all the perquisite header files such as and but the program crashes when i enter the data and then attempt to search. I get the circle of death and then program not responding then says Process returned 255 (0xFF) . It does not even out put Searching.... the program practically gives up as soon as I enter that name.
Also if this can be optimized by the use of pointers that would be great.
tl;dr run-time error causing the search to fail as soon as i type in a name. And for the record I have checked to make sure the name I entered is valid.
scanf doesn't know about std::string. Use std::cin >> league[i].TeamName.
scanf("%s", league[i].TeamName) ;
This should be changed to
std::cin >> league[i].TeamName ;
A couple of other things here....
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
Every time you input a value, you are telling the computer to hold the inputted value at decider[25] but the computer only reads indexes 0-24.
if(decider == league[i].TeamName){
Which array slot are you comparing the team name to? If its the 25th element than the statement should be
if(decider[24] == league[i].TeamName){
Pointers are better suited if the number of TeamNames are unknown. Based on the limited code presented, I highly recommend you stay within the realm of basic data types. For the purposes of troubleshooting, please post your full code in the future.
Your TeamName member variable:
string TeamName[MAX_CODENAME];
is an array of 25 strings, so in this line:
scanf("%s", league[i].TeamName) ;
you are courrupting the array. You don't really want an array anyways, so change the TeamName declaration to:
string TeamName;
and then when you read the name, you'll need to use iostreams which knows how to populate a string type (scanf only works with c char arrays):
std::cin >> league[i].TeamName

Getting strange value

I'm currently learning about functions in C++ and am currently working on a homework assignment with functions being the main thing.
Currently, I'm trying to make a grade calculator with every operation of the process being split into a function of its own.
Here's the code:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
void getHWGrades(int homeworks[], int size)
{
cout << "\nEnter the grades, out of 100 points, for the 9 homeworks you completed." << endl;
cout << "Note that Homework 10 is given to you for free, but is the same grade \nas homework 9.\n" << endl;
for (int i = 0; i < 9; i++)
{
cout << "Homework " << i + 1 << ": ";
cin >> homeworks[i];
while (homeworks[i] > 100 || homeworks[i] < 0)
{
cout << "Invalid grade, input homework grade again: ";
cin >> homeworks[i];
}
}
homeworks[9] = homeworks[8];
cout << "Homework 10: " << homeworks[9];
}
double quizAverage()
{
double quizPts;
cout << "Input your in class quiz average: ";
cin >> quizPts;
return quizPts;
}
double labAverage()
{
double labPts;
cout << "Input your lab average: ";
cin >> labPts;
return labPts;
}
double teamProject()
{
double teamPts;
cout << "Input your team project grade: ";
cin >> teamPts;
return teamPts;
}
int exam1()
{
int exam1Pts;
cout << "Input your exam1 grade: ";
cin >> exam1Pts;
return exam1Pts;
}
int exam2()
{
int exam2Pts;
cout << "Input your exam2 grade: ";
cin >> exam2Pts;
return exam2Pts;
}
double hwAverage(int homeworks[], int size)
{
double total = 0;
double homeworkAverage = 0;
for (int i = 0; i < size; i++)
{
total = total + homeworks[i];
}
homeworkAverage = (total*1.0) / 10;
return homeworkAverage;
}
double currentPoints(double& quizPts, double& labPts, double& teamPts, double& homeworkAverage, int& exam1Pts, int& exam2Pts)
{
double totalPts = ((quizPts / 100.0) * 10) + ((labPts / 100.0) * 10) + ((teamPts / 100.0) * 15) + ((homeworkAverage / 100.0) * 20) + ((exam1Pts / 100.0) * 10) + ((exam2Pts / 100.0) * 15);
cout << "\nYour current points (out of the 80 total available), stand at: " << totalPts;
return totalPts;
}
double currentAverage(double& totalPts)
{
double availableAverage = totalPts*(100.0 / 80);
cout << "\nYour current average is: " << availableAverage;
return availableAverage;
}
int main()
{
// keep the console from closing in visual studio
char charer;
double totalPts;
double quizPts, labPts, teamPts, homeworkAverage;
int exam1Pts, exam2Pts;
const int ARRAY_SIZE = 10;
int hwArray[ARRAY_SIZE];
getHWGrades(hwArray, ARRAY_SIZE);
quizAverage();
labAverage();
teamProject();
exam1();
exam2();
currentPoints(quizPts, labPts, teamPts, homeworkAverage, exam1Pts, exam2Pts);
currentAverage(totalPts);
cin >> charer;
}
My issue, which I believe lies in the functions currentPoints and currentAverage, is that when I run this totalPts outputs as -5.09078e+61 and as a follow up result with the currentAverage function, availableAverage outputs as -1.157e+62.
I'm sure that the issue has to do with how I'm passing the values from function to function (which I doubt I'm doing correctly).
How would I go about fixing this issue?
Thank you in advance.
You need to store the return value from currentPoints() function, like this.
totalPts = currentPoints(quizPts, labPts, teamPts, homeworkAverage, exam1Pts, exam2Pts);
currentAverage(totalPts);
Reason is, you declared "totalPts" as local variable in currentPoints().
"Local variables has function scope only, it is undefined to main function".
Do this for all other
functions(quizAverage,labAverage,teamProject,exam1,exam2, hwAverage,currentAverage)
I hope, this will solve the issue !!!
The problem is not about functions, it's about variables.
Let's take quizPts for instance:
In the main method, you declare this variable, but then you don't do anything with it before sending it to currentPoints. Therefore it has an undefined value when you do so (undefined often looks like random in C).
The other variable quizPts you use in quizAverage have the same name but is not the same for the compiler.
Try in your main:
quizPts = quizAverage();
You asked
How would I go about fixing this issue?
And the answer is "Use the debugging tool with "watches" window open in your favorite IDE".
It's always very difficult to find an error simply by re-reading the code, but in the debugger you can see all the values of your variables at each moment of time. Specifically, in this example, you would realize that your variables have garbage values from the very beginning (are not initialized), and this value never changes.
Using this approach you could find the reason yourself in time less than necessary to write this SO question. I hope this will help you to save your time in future.
The problem is you use the variables such as quizPts and labPts without storing any value in them. In your case, you have to store the return value of the function to the corresponding variable before using it. For example, do the same as the following statement:
quizPts = quizAverage();

Run Time Check failure #2:

Below is my code so far. I am just doing this step by step, for a class assignment. Trying not to give the whole code I just want to know what is wrong with what I have so I can learn to fix it. Thanks for the help.
The goal is to create class driver then to get total lap times, compare them and put them in order of 1st thru 3rd place. I've made this in a simple program already. Now I am trying to make an array of the class driver.
So far this is working, It asks for input correctly, and gives an output but before the end of the program I get:
Debug Error!
Run Time Check Failure #2 - Stack around the variable 'driver' was corrupted.
None of the answers I've found here make sense to my application. I have 0 failures when I run the build before running the program.
I also know not to use single character variables, I just do this as I learn what I'm missing and later change them.
#include <iostream>
#include <string>
using namespace std;
class Driver
{
int carNumber;
public:
void setNumber(int number)
{
carNumber = number;
}
int getNumber()
{
return carNumber;
}
};
int main()
{
int x;
int i;
Driver driver[3];
for (i = 1; i <= 3; i++)
{
cout << "Enter Driver " << i << "'s car number: ";
cin >> x;
driver[i].setNumber(x);
}
for (i = 1; i <= 3; i++)
cout << "driver " << i << "'s number is " << driver[i].getNumber() << endl;
return 0;
}
start for loop as shown below because as we know that array stores n elements from location 0 to n-1.
for (i = 0; i <3; i++)
{
cout << "Enter Driver " << i << "'s car number: ";
cin >> x;
driver[i].setNumber(x);
}
Your array access indexes are wrong.
Arrays start at index 0, not 1, and end at 1 less than the number of elements. So for a declaration of driver[3], the valid indexes are 0, 1, and 2, not 1, 2 and 3. With the wrong indexes, you're writing past the end of the array, causing the stack corruption.
Your write loop should be more like
for (i = 0; i < 3; i++)
{
cout << "Enter Driver " << i << "'s car number: ";
cin >> x;
driver[i].setNumber(x);
}
You'll need to make a similar fix to the read loop.

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.

Two-Dimensional Array addition problem

The problem was asking for employee numbers 1 through 10 (they gave me the array numbers to enter into the array) give the total sales for each employee by combining the 3 months together. In my addition function it does everything correctly....for the first part... It displays the numbers in the array perfectly but then when it goes to add the arrays and tosses out an element here and there resulting in incorrect totals. In my code I added that it should cout the array numbers that it is adding together after the first set of numbers it doesn't follow the array here is the code:
I followed what you guys were showing me (thank you btw) and I am now adding Employee #1's total to the rest which I do not want to do. I want to enter Employee #1's to each other stop display it then add Employee #2's total from the 3 numbers in the 3 months array stop display (continue until each piece is displayed 1~10) I have entered my new code for revision. I am new to C++ programming and I have not learned about classes yet so I honestly cannot use them.
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
void displaySales(int sales[10][3]);
void displayTotalSales(int total[10][3]);
int main ()
{
//declare array Jan Feb Mar
int employ[10][3] = {{2400, 3500, 2000},
{1500, 7000, 1000},
{600, 450, 2100},
{790, 240, 500},
{1000, 1000, 1000},
{6300, 7000, 8000},
{1300, 450, 700},
{2700, 5500, 6000},
{4700, 4800, 4900},
{1200, 1300, 400}};
//displays the sales for the month
displaySales(employ);
displayTotalSales(employ);
system("pause");
return 0;
}
//******Functions*******
void displaySales(int sales[10][3])
{
for(int emp = 0; emp < 10; emp++)
{
cout << "Employee # " << emp + 1
<< ": " << endl;
for (int month = 0; month < 3; month++)
{
cout << " Month " << month + 1
<< ": ";
cout << sales[emp][month] << endl;
} //end for
} //end for
} //end function
void displayTotalSales(int total[10][3])
{
int employ = 1; //employee number
int totalSales = 0; // total sales for the employee
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 3; j++)
{
totalSales += total[i][j];
cout << "Employee # " << employ << ": " << endl;
cout << endl;
cout << "Total sales for the month: " << "$" << total[i][j];
cout << endl;
}
cout << " Total Sales for the three months is: $" << totalSales << endl;
cout << endl;
employ++;
}
}
do {
...
totalSales = (total[i][j] + total[i][j+1] + total[i][j+2]);
j++;
} while (j < 3);
j goes out of bounds after the first iteration.
But seriously: Use classes! and Use containers!
Oh, and your curly brackets are totally messed up.
Its probably not appropriate for me to add this an answer but since there is no way for newbies to comment, I'll just say it here.
I agree with karl regarding learning about objects. when we learned about c and c++ at college we started out with structs and then moved on to classes and its really important to learn this stuff if you're serious about programming.
a class is just a way of describing an object in the real world. it has attributes and behaviours. For example you could have an employee class that could store all their earnings per month and it could have a function within it that allows you to calculate their recent earnings. These small additions to your code will make it easier to read, organise and reuse.
I seriously suggest you spend a few hours googling object oriented concepts and try some c++ examples. they're very easy.
First of all please form your code better! Indenting would make this a hell of a lot easier to understand and help you with.
I get the strong feeling that this is a homework question for a programming class but I'll try and help you with it anyway.
Basically your problem is that you are running over the end of the array, because when j == 2 for example when you use the statement:
totalSales = (total[i][j] + total[i][j+1] + total[i][j+2]);
you are trying to reference j+2 which is actually the 5th element of the array, which does not exist.
I did a 10 second rewrite of your addFunk (please name functions better)
You could try something like this:
void addFunk(int total[10][3])
{
int employ = 1; //employee number
int totalSales = 0; // total sales for the employee
for (int i = 0; i < 10; i++)
{
for ( int j = 0; j < 3; j ++)
{
totalSales += total[i][j];
}
cout << "employee num " << employ << "earned "
<< "$" << totalSales << endl;
totalSales = 0;
employ++;
totalSales = 0;
}
}
Regarding your update to the code, you say:
I am now adding Employee #1's total to the rest which I do not want to do.
The problem is this line:
int totalSales = 0; // total sales for the employee
Look at the comment you've put there: it's per-employee. Therefore, it should go inside the "per-employee loop":
for (int i = 0; i < 10; i++)
{
int totalSales = 0;
// Proceed as before with the per-month work.
Please read up about the "scope" of variables in C++.
Also, being new to C++, or new to programming in general, is not really an excuse to avoid classes. There's nothing particularly advanced about them per se; the code is only as complicated as you make it - and classes exist because using them properly helps organize (read: simplify) your code.