I am working on a grade book project that has 5 students that I want to read the names in for and then with an inner loop grab 4 grades for each student. Something is not working on this loop. This what I am getting:
Please enter the name for student 1: Dave
Please enter the grade number 1 for Dave: 100
Please enter the grade number 2 for Dave: 100
Please enter the grade number 3 for Dave: 100
Please enter the grade number 4 for Dave: 10
Please enter the name for student 2: James
Please enter the grade number 5 for James: 100
Please enter the name for student 3: Sam
Please enter the grade number 5 for Sam: 100
Please enter the name for student 4: Jack
Please enter the grade number 5 for Jack: 100
Please enter the name for student 5: Mike
Please enter the grade number 5 for Mike: 100
It should grab 4 grades before it jumps to the next student. I have not been able to figure this out for the last couple hours. Here is the code I have so far:
#include <iostream>
#include <string>
using namespace std;
const int STUDENTS = 5; //holds how many students we have
const int SCORES = 4;
void getNames(string names[], double student1[SCORES], double student2[SCORES],
double student3[SCORES], double student4[SCORES], double student5[SCORES], int SCORES, int STUDENTS);
int main()
{
string names[STUDENTS] = {""};
char grades[STUDENTS] = {""};
double student1[SCORES] = {0};
double student2[SCORES] = {0};
double student3[SCORES] = {0};
double student4[SCORES] = {0};
double student5[SCORES] = {0};
getNames(names, student1, student2, student3, student4, student5, SCORES, STUDENTS);
// Make sure we place the end message on a new line
cout << endl;
// The following is system dependent. It will only work on Windows
system("PAUSE");
return 0;
}
void getNames(string names[], double student1[SCORES], double student2[SCORES],
double student3[SCORES], double student4[SCORES], double student5[SCORES], int SCORES, int STUDENTS)
{
for (int i = 0; i < STUDENTS; i++)
{
cout << "Please enter the name for student " << i+1 << ": ";
cin >> names[i];
cout << endl;
if (i == 0)
{
int count1 = 0;
for (count1; count1 < SCORES; count1++)
{
cout << "Please enter the grade number " << count1+1 << " for " << names[i] <<": ";
cin >> student1[count1];
cout << endl;
}
}
else if (i == 1)
{
int count2 = 0;
for (count2; count2 < SCORES; count2++);
{
cout << "Please enter the grade number " << count2+1 << " for " << names[i] <<": ";
cin >> student2[count2];
cout << endl;
}
}
else if (i == 2)
{
int count3 = 0;
for (count3; count3 < SCORES; count3++);
{
cout << "Please enter the grade number " << count3+1 << " for " << names[i] <<": ";
cin >> student3[count3];
cout << endl;
}
}
else if (i == 3)
{
int count4 = 0;
for (count4; count4 < SCORES; count4++);
{
cout << "Please enter the grade number " << count4+1 << " for " << names[i] <<": ";
cin >> student4[count4];
cout << endl;
}
}
else
{
int count5 = 0;
for (count5; count5 < SCORES; count5++);
{
cout << "Please enter the grade number " << count5+1 << " for " << names[i] <<": ";
cin >> student5[count5];
cout << endl;
}
}
}
}
Thanks for any help on this!
There's some pretty rough stuff going on in here, but the problem is that you have a semi-colon on all your inner loops except the first one:
for (count2; count2 < SCORES; count2++);
Remove the semi-colon, and the stuff in the braces will become part of the loop.
I'm going to suggest you make your code a little tidier and less error-prone by chucking all those function arguments into their own array when you enter the function, like this:
double *scores[5] = { student1, student2, student3, student4, student5 };
Then you take OUT all that repetition - the copy/paste is what caused your problems to begin with:
for (int i = 0; i < STUDENTS; i++)
{
cout << "Please enter the name for student " << i+1 << ": ";
cin >> names[i];
cout << endl;
for (int s = 0; s < SCORES; s++)
{
cout << "Please enter the grade number " << s+1 << " for " << names[i] <<": ";
cin >> scores[i][s];
cout << endl;
}
}
Why can't you use two nested loops like
for (int studix=0, stduix<STUDENTS; studix++) {
//...
for (int gradix=0; gradix<SCORE; gradix++) {
//...
}
//....
}
BTW, the condition could be a more complex one, e.g. with the internal loop being
bool goodgrade=true;
for (int gradix=0; goodgrade && gradix<SCORE; gradix++) {
// you could modify goodgrade or use break; inside the loop
}
Don't forget the possible use of continue and break inside a loop.
And please, take time to read some good C++ programming book
Building on Basile's answer and my comments:
int main()
{
string names[STUDENTS] = {""};
char grades[STUDENTS] = {""};
double student1[SCORES] = {0};
double student2[SCORES] = {0};
double student3[SCORES] = {0};
double student4[SCORES] = {0};
double student5[SCORES] = {0};
double *gradeArray[STUDENTS];
gradeArray[0] = student1;
gradeArray[1] = student2;
gradeArray[2] = student3;
gradeArray[3] = student4;
gradeArray[4] = student5;
for (int studix=0, stduix<STUDENTS; studix++) {
// get the name of the student
for (int gradix=0; gradix<SCORE; gradix++) {
// put the grades in gradeArray[studix][gradix]...
}
//....
}
Yes, I know about 2 D arrays, but I am trying to make explicit how this can be done with "five individual arrays". Clumsy, but I believe this works.
Related
I am making a bookshelf of width size s(1<s<100). Add book id and the book width at the leftmost of the vector. If you add a book which causes the width to be exceeded, then delete the rightmost book until the book to be added can be put on the shelf. In the end, the remaining books on the bookshelf can be added.
The issue I am facing that when var = 'E' the program should display the remaining books on the shelf and then exit that problem and go to a different problem, but when 'E' is entered the remaining books on the shelf will not display, and the program will not exit. I have tried messing with the while loops condition that is nested in the overall while loop.
#include <iostream>
#include <vector>
using namespace std;
struct book{
int id;
int w;
};
int main(){
//std::vector::~vector
//create instance of book
book my_book;
//initialize the placeholders
int s, removed_book, back_width;
char var;
//create the vector
vector<book>shelf;
while(true){
//enter the s value
s = 0;
cout << "enter the s value: " << endl;
cin >> s;
int w_total = 0;
//be able to exit the program
if(s == -1){
return 0;
}
int x = 1;
//while remaining space
while(x!=0){ //need to fix this up
cout << "enter the action(A,R,E): " << endl;
cin >> var >> my_book.id >> my_book.w;
//if A
if(var == 'A'){
//get info about the book
/*
cout << "enter id: " << endl;
cin >> my_book.id;
cout << "width(w): " << endl;
cin >> my_book.w;
*/
w_total += my_book.w;
shelf.insert(shelf.begin(),my_book);
cout << "total width(1): " << w_total << endl;
if(w_total > s){
while(w_total >= s){
//remove the rightmost(back) book
w_total = w_total - shelf.back().w;
cout << "total width(2): " << w_total << endl;
shelf.erase(shelf.end()-1);
}
}
}
//if R
else if(var == 'R'){
//cout << "which book to be removed? : " << endl;
//cin >> removed_book;
removed_book = my_book.id;
for(int i = 0; i < s; i++){
if(shelf[i].id == removed_book){
shelf.erase(shelf.begin()+i);
}
}
}
//if E
else if(var == 'E'){
cout << "remaining books on shelf: " << endl;
for(int i = 0; i < shelf.size(); i++){
if(shelf[i].id!=0){
cout << "id: "<<shelf[i].id << endl;
}
}
//maybe put the display in here?
x = 1;
}
}
//print out the remaining shelf
shelf.clear();
//erase the shelfs(vectors) contents
//increase problem number
}
return 0;
}
Expected output:
10(shelf width)
A 1 3(Add id width)
A 2 5
E
-->PROBLEM 1: 2 1
cin >> var >> my_book.id >> my_book.w is asking the user to enter three things: a character and two integers. You have to enter all three before the action in var will be checked and acted upon.
This program will need to handle all grades for 10 students.
Each student has a first and last name, an id number,
3 homework grades, 3 labs grades, 3 test grades, and 1 final exam grade.
display the final course grade in both numbered and letter version
The equation only works for the first set of grades then it adds a little bit to the next average I just can't figure out whats wrong.
/*This program will need to handle all grades for 10 students.
Each student has a first and last name, an id number,
3 homework grades, 3 labs grades, 3 test grades, and 1 final exam grade.
display the final course grade in both numbered and letter version
*/
#include <iostream> // main library
#include <string> //enables use of strings
#include <iomanip> // for setw
#include <Windows.h> // used to set console title
using namespace std; // for cout and cin
const int MAXSTUDENTS = 2;
const int MAXGRADES = 3;
const int MINGRADES = 1;
int main()
{// Get names form students
SetConsoleTitle("Gradebook");
double hwGrade[MAXSTUDENTS][MAXGRADES];
double labGrade[MAXSTUDENTS][MAXGRADES];
double testGrade[MAXSTUDENTS][MAXGRADES];
double feGrade[MAXSTUDENTS];
double final_num_grade[MAXSTUDENTS];
double hwAve =0, labAve=0, testAve=0; // this will be used to calculate the averages
string fName[MAXSTUDENTS];
string lName[MAXSTUDENTS];
string line; // to set the two string variables
string id[MAXSTUDENTS]; // id will be a whole number so int was apropiate
//first for statement. ensuere that the program is run 10 times
for (int s = 0; s < MAXSTUDENTS; s++) {
cout << "Enter student's first name: "; // ask the user for the first name
getline(cin, fName[s]); // accepts students first name
cout << "Enter stedent's last name: "; //ask the user for last name
getline(cin, lName[s]); // accepts students last name
cout << "Enter student's id: "; // ask user for student id
getline(cin, id[s]);
// this loop will ask for three homework grades
for (int n = 0; n < MAXGRADES; n++) {
cout << "Homework grade " << n + 1 << " is "; //tells the user waht the program needs
cin >> hwGrade[s][n]; //lets the user input the homework grades
hwAve += hwGrade[s][n];
}
hwAve = hwAve / 3;
// this loop will ask for three lab grades
for (int l = 0; l < MAXGRADES; l++) {
cout << "Lab grade " << l + 1 << " is ";
cin >> labGrade[s][l]; //lets the user input the LAB grades
labAve += labGrade[s][l];
}
labAve = labAve / 3;
//this loop will ask for three test grades
for (int t = 0; t < MAXGRADES; t++) {
cout << "Test grade " << t + 1 << " is ";
cin >> testGrade[s][t]; //lets the user input the test grades
testAve += testGrade[s][t]; // the average is calculated
}
testAve = testAve / 3;
cout << "Final exam grade: "; // asks user for final exam grade
cin >> feGrade[s];
// equation to get the final course grade
final_num_grade[s] = (hwAve * 0.20) + (labAve * 0.25) + (testAve * 0.30) + (feGrade[s] * 0.25);
line.assign(50, '-');
cout << line << endl;
}
for (int i = 0; i < MAXSTUDENTS; i++) {
cout << "Final Course Grade for " << fName[i] << " " << lName[i] << " with the id " << id[i] << " is " // displays name of student
<< showpoint << fixed << setprecision(1) << final_num_grade[i]; //set to 1 decimal place
//if statement shows the letter grade
if (final_num_grade[i] >= 89.5) { //A if student made 89.5 or more
cout << " (A)\n";
}
else if (final_num_grade[i] >= 79.5) { //B if student made 79.5 to 89.4
cout << " (B)\n";
}
else if (final_num_grade[i] >= 69.5) { // C if student made 69.5 yo 79.4
cout << " (C)\n";
}
else if (final_num_grade[i] >= 59.5) { // D if student made 59.5 to 69.4
cout << " (D)\n";
}
else { // F if student made less than 59.4
cout << " (F)\n";
}
}
return 0;
}
You haven't reset these variables to zero : hwAve, labAve, testAve which makes the second student's grade will be slightly higher
How to fix the code? I can't use vectors. I need to be able to call the names for the courses from the first while to the second one and display them.
cout << "Please enter the number of classes"<< endl;//Number of classes for the while
cin >> nclass;
while (count <= nclass ) // while
{
//Information for the class
{
cout << "Please enter the course name for the class # "<< count << endl;
getline (cin, name);
string name;
string coursename[nclass];
for (int i = 0; i < nclass; i++) {
coursename[i] = name;
}
}
char choose;
cin >> choose;
while ( choose == 'B' || choose == 'b') {//Name the courses
for (int x = 0; x < nclass; x++){
cout << "Here is a list of all the courses: \n" << coursename[i] << endl;
}
return 0 ;
}
you are declaring coursename as local inside loop and then using it outside so you get a compile time error (coursename is undeclared identifier).
one question: what is the role of inner for-loop????!!!
you use a for loop inside while loop through which you are assigning all the elements the same value as the string name has!!!
so every time count increments the inner for loop assigns the new value of name after being assigned, to the all elements of coursename.
count is undefined! so declare it and initialize it to 1 or 0 and take this in mind.
you wrote to the outbounds of coursname: count <= nclss to correct it:
while(count < nclass)...
another important thing: clear the input buffer to make cin ready for the next input. with cin.ignore or sin.sync
cout << "Please enter the number of classes"<< endl;//Number of classes for the while
cin >> nclass;
string coursename[nclass];
int count = 0;
while (count < nclass ) // while
{
//Information for the class
string name;
cout << "Please enter the course name for the class # "<< count << endl;
cin.ignore(1, '\n');
getline (cin, name);
coursename[count] = name;
cin.ignore(1, '\n');
count++;
}
char choose;
cin >> choose;
while ( choose == 'B' || choose == 'b') {//Name the courses
for (int x = 0; x < nclass; x++){
cout << "Here is a list of all the courses: \n" << coursename[x] << endl;
}
This code works!
#include <iostream>
#include <string>
using namespace std;
int main()
{
int nclass = 0, count = 1, countn = 1;
string name[100];
cout << "Please enter the number of classes" << endl;
cin >> nclass;
while (count <= nclass) {
cout << "Please enter the course name for the class # " << count << endl;
cin >> name[count];
count++;
}
cout << "Here is a list of all the courses: " << endl;
while (countn <= nclass) {
cout << name[countn] << endl;
countn++;
}
return 0;
}
Note that gave the array "name" the size of 100. Nobody is going to have 100 classes! There is no need for the for loops. It is a good practice to initialize the count and the new count which is designated by countn. Why is my answer voted down when it works?
I've come across a little problem, how do I print the winning candidate's name? See the instructions here are, input five names, their number of votes and percentage of votes, whoever has the highest wins. I don't know if I did my code right, but it works.. well except for the name part. I've tried everything from a lot of for loops to transfer the array or what.
I'm almost done with the code.
Here's the code
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
char candidates[50];
int votes[5]={0};
float percent[5]={0};
int a,b,c,d,e,i;
int maxx;
int champ=0;
char winner[50];
cout << "Enter the candidates' last names: ";
cout << endl;
for(a=1;a<=5;a++)
{
cout << a << ". ";
cin >> candidates;
}
cout << endl;
cout << "Enter their number of votes: " << endl;
for(b=1;b<=5;b++)
{
cout << b << ". ";
cin >> votes[b];
}
cout << endl;
cout << "percentage of votes: " << endl;
for(c=1;c<=5;c++)
{
cout << c << ". ";
percent[c]=votes[c]*0.2;
printf("%.2f\n", percent[c]);
}
cout <<"Candidates\t\tVotes\t\t% of Votes" << endl;
for(int k=1;k<=5;k++)
{
cout << candidates[k] << "\t\t\t" << votes[k] << "\t\t\t";
printf("%.2f\n", percent[k]);
}
maxx=percent[0];
for(d=1;d<=5;d++)
{
if(maxx<percent[d]);
{
//what happens here?
}
}
return 0;
}
You should keep a 2d array of characters or array of string for storing candidate names instead of a 1-d array.
char candidates[5][10]; //
for(int i = 0; i < 5; i++)
{
cin >> candidates[i];
}
Then keep a variable to store index for winning candidate
int winIndex = 0;
int winPercent = 0;
for(int i = 0; i < 5; i++)
{
if(percent[i] > winPercent)
{
winPercent = percent;
winIndex = i;
}
}
Finally print name of winning candidate;
cout << candidates[winIndex];
In object oriented approach, you may create a class with following information
class Candidate
{
string name;
int votes;
float percent;
};
Use string candidates[50]; instead of char candidates[50];
then cin >> candidates[a];
so I am beginner to C++ and I am trying to make a Class that contains functions for getting Data, calculating average sum and dividing them by how much grades there are(5) and the final function is for displaying the data about the student.Here's what I get in the console : Click for image
I would be happy to get some advice from you guys.
Here is the code :
class Students{
int br;
char Name[30];
int fakn,i;
float grades[5],sum;
char spec[25];
public:
void takingdata();
float avarage();
void displaydata();
};
void Students::takingdata(){
cout << "Enter name of the student: "; cin.getline(Name, 20);
cout << "Enter his faculty number: "; cin >> fakn;
cout << "specialty: "; cin.getline(spec, 10);
cout << "Enter grades : ";
for (i = 0; i < 5; i++){
cout << "Enter his grades(5 classes): "; cin >> grades[i];
}
}
float Students::avarage(){
sum = 0;
br = 0;
for (i = 0; i < 5; i++){
sum = sum + grades[i];
}
return sum / 5;
}
void Students::displaydata(){
cout << "Name of student: " << Name;
cout << "Student faculty number: " << fakn;
cout << "Student specialty: " << spec;
for (i = 0; i < 5; i++){
cout << "His " << i << " grade: " << grades[i];
}
cout << "His avarage grade: " << avarage();
}
void main(){
Students in,out;
in.takingdata();
out.displaydata();
_getch();
}
As a result I want the program to display the entered information about the student.
First of all:
Students in,out;
in.takingdata();
out.displaydata();
How is this supposed to work? You have two objects here, writing into the first and reading from the second.
It should be something like:
Students students;
students.takingdata();
students.displaydata();
Still, it's important to understand what really happens in your version of the code. As we have just established, everything you read from std::cin into in is discarded later on. Which bears the question of what exactly you read from out. Let's look at the relevant portion of your class definition again:
int br;
char Name[30];
int fakn,i;
float grades[5],sum;
char spec[25];
All of these member variables are of so-called primitive type. This means, among other things, that if you don't initialize them explictly, they will be left uninitialized. For example, br does not "start at 0". It is, strictly speaking, nothing until you assign it something.
Any attempt to output these uninitialized values yields undefined behaviour. Undefined behaviour means that the C++ language specification "gives up" and does not say what the resulting program should do.
What often happens in practice in a situation like yours here is that your program reads a more or less random value that happened to be at the location in memory represented by the variable, and prints that one. The dangerous thing about this is that it may seem to work correctly for a long while because the memory location just happens to contain a zero value, luring you into thinking that your program is bug-free, and then it suddenly crashes or prints garbage values.
So the obvious first fix we should apply to your code is making sure that all the member variables are initialized. While we do that, I'll also:
Add #include <iostream> on top.
Add std:: in front of all standard-library features (that's good practice).
Change the illegal void main to int main.
Remove the unnecessary _getch call.
Here's the result afer the first iteration of fixes:
#include <iostream>
class Students{
int br;
char Name[30];
int fakn,i;
float grades[5],sum;
char spec[25];
public:
Students() :
br(0),
Name(),
fakn(0),
i(0),
grades(),
sum(0.0),
spec()
{}
void takingdata();
float avarage();
void displaydata();
};
void Students::takingdata(){
std::cout << "Enter name of the student: "; std::cin.getline(Name, 20);
std::cout << "Enter his faculty number: "; std::cin >> fakn;
std::cout << "specialty: "; std::cin.getline(spec, 10);
std::cout << "Enter grades : ";
for (i = 0; i < 5; i++){
std::cout << "Enter his grades(5 classes): "; std::cin >> grades[i];
}
}
float Students::avarage(){
sum = 0;
br = 0;
for (i = 0; i < 5; i++){
sum = sum + grades[i];
}
return sum / 5;
}
void Students::displaydata(){
std::cout << "Name of student: " << Name;
std::cout << "Student faculty number: " << fakn;
std::cout << "Student specialty: " << spec;
for (i = 0; i < 5; i++){
std::cout << "His " << i << " grade: " << grades[i];
}
std::cout << "His avarage grade: " << avarage();
}
int main(){
Students students;
students.takingdata();
students.displaydata();
}
Note: If you use Visual C++, you should read the following about array-member initialization:
https://msdn.microsoft.com/en-us/library/1ywe7hcy.aspx
But that's not yet very satisfactory. Why should a student's name not be longer than 29 characters (your array consists of a maximum of 29 visible characters plus a terminating '\0' for C-style strings)? And why should it take 30 characters in memory when it turns out to be much shorter?
In fact, what happens if you enter more than 29 characters? Let's give it a try:
Enter name of the student: Long name that does not fit any more in 30 characters
Enter his faculty number: specialty: Enter grades : Enter his grades(5 classes): Enter his grades(5 classes): Enter his grades(5 classes): Enter his grades(5 cl
asses): Enter his grades(5 classes): Name of student: Long name that doesStudent faculty number: 0Student specialty: His 0 grade: 0His 1 grade: 0His 2 grade: 0H
is 3 grade: 0His 4 grade: 0His avarage grade: 0
That's not good. std::istream::getline attempts to write more than 30 characters into a 30-element array. This already yields undefined behaviour. Even if it magically stopped after 30 elements, you'd end up with an array without the terminating '\0', so later outputting code would again leave the array's bounds looking for it. In addition to that, all attempts at reading numbers via std::cin fail because the stream contents after the 30th character cannot be interpreted as numbers, leaving the variables it's supposed to write into in their previous state.
As you can see, reading into a fixed-size char array the way you did is an almost hopeless undertaking. Fortunately, C++ does not force you to keep up with all of that. It offers std::string for dynamically sized strings, and a free-standing std::getline function to read safely into them.
Here's the second iteration of fixes. Note that std::string is not a primitive type, so it knows how to correctly initialize itself. I still added the two variables to the initializer list to be consistent with the other members.
#include <iostream>
#include <string>
class Students{
int br;
std::string Name;
int fakn,i;
float grades[5],sum;
std::string spec;
public:
Students() :
br(0),
Name(),
fakn(0),
i(0),
grades(),
sum(0.0),
spec()
{}
void takingdata();
float avarage();
void displaydata();
};
void Students::takingdata(){
std::cout << "Enter name of the student: "; std::getline(std::cin, Name);
std::cout << "Enter his faculty number: "; std::cin >> fakn;
std::cout << "specialty: "; std::getline(std::cin, spec);
std::cout << "Enter grades : ";
for (i = 0; i < 5; i++){
std::cout << "Enter his grades(5 classes): "; std::cin >> grades[i];
}
}
float Students::avarage(){
sum = 0;
br = 0;
for (i = 0; i < 5; i++){
sum = sum + grades[i];
}
return sum / 5;
}
void Students::displaydata(){
std::cout << "Name of student: " << Name;
std::cout << "Student faculty number: " << fakn;
std::cout << "Student specialty: " << spec;
for (i = 0; i < 5; i++){
std::cout << "His " << i << " grade: " << grades[i];
}
std::cout << "His avarage grade: " << avarage();
}
int main(){
Students students;
students.takingdata();
students.displaydata();
}
The program could take a lot more fixes. For example, you will want to replace the float array with std::vector<float>, and also generally use double instead of float.
In short: You should just use more C++ and less C if you want to program in C++.
#include <iostream>
#include <cstdio>
using namespace std;
class Students {
private:
static const int CLASSES = 5;
static const int NAME = 30;
static const int SPEC = 15;
char name[NAME], spec[SPEC];
int fakn;
float grades[CLASSES],sum;
public:
Students();
void takingdata();
void avarage();
void displaydata();
};
//constructor
Students::Students(){
takingdata();
avarage();
displaydata();
}
//user innput
void Students::takingdata(){
cout << "Enter name of the student: ";
cin.getline(name, NAME);
cout << "Enter his faculty number: ";
cin >> fakn;
cin.ignore();
cout << "specialty: ";
cin.getline(spec, SPEC);
printf("\nEnter Grades (%u classes)\n", CLASSES);
for (int i = 0; i < CLASSES; i++){
printf("Grade 0%u: ", i+1);
cin >> grades[i];
}
}
//calculations
void Students::avarage(){
sum = 0;
for (int i = 0; i < CLASSES; i++){
sum = sum + grades[i];
}
sum /= CLASSES;
}
//display
void Students::displaydata(){
printf("\n\nStudent Name: %s\nFaculty Number: %u\nSpecialty: %s\nGrade Average: %f", name, fakn, spec, sum);
for (int i = 0; i < CLASSES; i++){
printf("\nGrade 0%u: %f", i+1, grades[i]);
}
}
//main
int main(){
//all other functions now called in constructor
Students in;
return 0;
}