Why does the while loop not break? - c++

This program takes the name of the course, grade and the number of units of a course to calculate the grade point average. I want the program to exit the while loop after the user enters the letter q and display the phrase outside the loop.
#include <iostream>
using namespace std;
int main()
{
char name[20];
float unit;
float score;
float avg = 0;
float total = 0;
int q=0, c=0;
while (name[20]!= q)
{
cout << "Enter a Name";
cin >> name;
cout << "Enter score";
cin >> score;
cout << "Enter unit of surce";
cin >> unit;
avg = avg + score * unit;
total = total + unit;
cout << "cantinue(c) or break(q)";
cin >> name[20];
}
avg = avg / total;
cout << "gpa :" << " " << avg;
return 0;
}

Problem:
You're comparing a char with an int variable called q. That won't break the loop when the user enters 'q', it will break the loop when the player enters the character that corresponds to the value that the q variable stores (in your case it is probably 0 in ASCII that is '\0').
Additionally, you're accessing a variable that is out of the bonds of the array which is Undefined Behaviour. You should write name[19] instead.
Solution:
Compare name[19] to 'q' instead.
while(name[19] != 'q')
...
std::cin >> name[19];
Additional information:
using namespace std; is considered a bad practice (More info here).
During the first check of the while condition your char variable is uninitializated, which will result in Undefined Behaviour. Solve this initialazing it to some value or using a do while loop instead;
I would recommend to create an additional char variable to store the character that controls the exit.
Full code:
#include <iostream>
int main()
{
char name[20];
float unit;
float score;
float avg = 0;
float total = 0;
char quit;
do
{
std::cout << "Enter a Name: ";
std::cin >> name;
std::cout << "Enter score: ";
std::cin >> score;
std::cout << "Enter unit of source: ";
std::cin >> unit;
avg = avg + score * unit;
total = total + unit;
std::cout << "Continue(c) or break(q): ";
std::cin >> quit;
} while(quit != 'q');
avg = avg / total;
std::cout << "gpa :" << " " << avg;
return 0;
}

Related

why is my code not accepting letters as user input

my code runs without errors or anything but after I put in an "F" or "P" it skips to "click any button to continue" but if I use any numbers it goes through the code fine.
Here is my code:
#include <iostream>
#include <iomanip> // needed to use set precision
using namespace std;
void calcCost(double f_benefits, double F, double total_cost, double emp_salary)
{
if (f_benefits == F)
(total_cost += emp_salary * 1.5);
else
(total_cost += emp_salary * 1.25); // calculating operating function
}
int main()
{
double num_emp = 0; // employees
double emp_salary = 0; // employees salary
double f_benefits = 0; // are they full time or part time benifits
double total_cost = 0;
int F = 0;
int P = 0;
cout << setw(69) << "Cost of Operation\n\n";
cout << "Please enter the number of employees to process: ";
cin >> num_emp;
cout << endl;
for (int i = 1; i <= num_emp; i++) // loop for each employees salary and benifits
{
cout << "Please enter the salary for employee " << i << ":";
cin >> emp_salary;
cout << "Is employee " << i << " receiving(F)ull or (P)artial benefits ? Please enter F or P : "; // Dont forget input validation for this step
cin >> f_benefits;
}
return 0;
}
Shouldn't f_benefits be a string?
The "cin >> f_benefits" is trying to read a double value. You should read the response into a char or string. Reading into a string expects a newline before returning.
You should also check that you got an "F" or "P" .

C++ How to return array of objects from a function

recently I have started learning c++, so I'm trying to make a simple grade calculator using my base knowledge (I'm already good with Javascript so i know the basics of programming).
So in this case, I had to return an array of objects from a function call so i can use it later in the program, but I just couldn't find the right way to do so.
So basically i want to return subArr from the getInput function, but I couldn't do that due to my basic knowledge in the language. I tried googling but didn't find any simple solution.
Here is the code and hope it is simple:
//the Subject class:
class Subject {
public:
string name;
float grade;
int factor;
Subject(){};
Subject(string x, float y, int z){
name = x;
grade = y;
factor = z;
}
};
//get Input function declaration
Subject getInput(int num){
//array of objects of type "Subject"
Subject subArr[num];
//a for loop to assign the array's elements
for(int i = 0; i < num; i++){
string name;
float grade;
int factor;
cout << "what is the name of subject " << i+1 <<"? "<<endl;
cin >> name;
cout << "what is the grade of subject " << i+1 << "? "<<endl;
cin >> grade;
cout << "what is the factor of subject " << i+1 << "? "<<endl;
cin >> factor;
subArr[i]=Subject(name, grade, factor);
};
//trying to return the subArr at last
return subArr;
};
//main function
int main(){
//get the number of subjects
int numOfSubjects;
cout << "how many subjects are there? ";
cin >> numOfSubjects;
//trying to receive the subArr from getInput call
Subject subArr = getInput(numOfSubjects);
};
Use std::vector:
#include <iostream>
#include <vector>
using namespace std;
// the Subject class
class Subject {
public:
string name;
float grade;
int factor;
Subject(){};
Subject(string x, float y, int z){
name = x;
grade = y;
factor = z;
}
};
// get Input function declaration
vector<Subject> getInput(int num){
// array of objects of type "Subject"
vector<Subject> subArr;
// a for loop to assign the array's elements
for(int i = 0; i < num; i++){
string name;
float grade;
int factor;
cout << "what is the name of subject " << i+1 <<"? "<<endl;
cin >> name;
cout << "what is the grade of subject " << i+1 << "? "<<endl;
cin >> grade;
cout << "what is the factor of subject " << i+1 << "? "<<endl;
cin >> factor;
subArr.push_back(Subject(name, grade, factor));
};
// trying to return the subArr at last
return subArr;
};
// main function
int main(){
// get the number of subjects
int numOfSubjects;
cout << "how many subjects are there? ";
cin >> numOfSubjects;
// trying to receive the subArr from getInput call
vector<Subject> subArr = getInput(numOfSubjects);
};

Display Student ID and highest score from an array

I am having issues figuring out how to properly display a student's ID, out of 10 students, along with the highest score. For examle, if student 4 had the highest score if would display said student's ID and their score. I would like to add the student's first and last name as well, if possible. My code is as follows:
// HW2.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include <iostream>
using namespace std;
double TestScore(double score);
struct studentType {
string studentFName;
string studentLName;
double testScore;
int studentID;
double highScore;
};
int main()
{
// # of students
studentType student[10];
// For loop to get user input for the 10 students
for (int i = 0; i < 10; i++) {
cout << "Student ID: ";
cin >> student[i].studentID;
cout << "Student First Name: ";
cin >> student[i].studentFName;
cout << "Student Last Name: ";
cin >> student[i].studentLName;
cout << "Student's Test Score: ";
cin >> student[i].testScore;
cout << endl;
//Calls TestScore function
student[i].testScore = TestScore(student[i].testScore);
}
//Displays student ID and score v code that I need help on
//cout <<student[i].studentID << " has the highest score, which is "<< TestScore;
}
double TestScore(double score)
{
double newScore = 0;
//Determines student with highest score
for (int n = 0; n < 10; n++) {
if (score > newScore)
{
newScore = score;
}
}
return newScore;
}
It needs to :
1) read the students’ data into the array.
2) find the highest test score.
3) print the names of the students having the highest test score.
Your TestScore function doesn't really do anything. I've modified your code to have a function which returns the index of the student with the best score. Using this index, you can then access that element of the array, and print out its details.
#include <iostream>
using namespace std;
struct studentType {
string studentFName;
string studentLName;
double testScore;
int studentID;
double highScore;
};
int getBestStudent( studentType student[10] );
int main() {
// # of students
studentType student[10];
// For loop to get user input for the 10 students
for ( int i = 0; i < 10; i++ ) {
cout << "Student ID: ";
cin >> student[i].studentID;
cout << "Student First Name: ";
cin >> student[i].studentFName;
cout << "Student Last Name: ";
cin >> student[i].studentLName;
cout << "Student's Test Score: ";
cin >> student[i].testScore;
cout << endl;
}
// Displays student ID and score v code that I need help on
int best = getBestStudent( student );
cout <<student[best].studentFName << " " << student[best].studentLName << " has the highest score, which is "<< student[best].testScore;
}
int getBestStudent( studentType student[10] ) {
int best = 0;
//Determines student with highest score
for ( int n = 1; n < 10; n++ ) {
if ( student[n].testScore > student[best].testScore ) {
best = n;
}
}
return best;
}```

Displaying gibberish and missing operations

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

Loop accepts first set of input and then reuses that value

I am currently learning C++ in school and one of our projects is to create a program to calculate a budget. When I run my program, the loop that accepts the input for item cost will take the input once and then reuse that value each time it loops back. I have already searched online for a solution and my teacher is just as confused about it as I am. It could be that there is a problem with Codeblocks but I have already tried it with a different editor. If anyone knows how I can fix it, that would be great.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Declares variables
float itemCount = 0;
float taxPercent = 0;
float itemCost = 0;
bool taxable = true;
float totalTaxable = 0;
float totalNontaxable = 0;
float total = 0;
//Receive user input
cout << "How many items to you have to buy: ";
cin >> itemCount;
cout << "\nWhat is the tax percentage (do not include the % sign): ";
cin >> taxPercent;
//This code runs once for every item
while (itemCount > 0){
//Receive the remaining user input
cout << "\nWhat is the cost of the item: ";
cin >> itemCost;
cout << "\nIs the item taxable (Please use either true or false): ";
cin >> taxable;
//Adds the item cost to either the taxable or nontaxable variables
if (taxable == true){
totalTaxable += itemCost;
cout << "true";
} else{
totalNontaxable += itemCost;
cout <<"false";
}
itemCount -= 1;
}
total = (totalTaxable * (1 + (taxPercent / 100))) + totalNontaxable;
cout << "\n--------------------------------------------------\n";
cout << "You must earn $";
cout << total;
cout << " to meet this budget\n\n";
}
As said in the comment, you can't use cin on boolean. From the doc :
The standard input stream is a source of characters determined by the environment.
So here's your fixed code (which will accept Y and nothing else) :
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
//Declares variables
float itemCount = 0;
float taxPercent = 0;
float itemCost = 0;
char taxable = '';
float totalTaxable = 0;
float totalNontaxable = 0;
float total = 0;
//Receive user input
cout << "How many items to you have to buy: ";
cin >> itemCount;
cout << "\nWhat is the tax percentage (do not include the % sign): ";
cin >> taxPercent;
//This code runs once for every item
while (itemCount > 0){
//Receive the remaining user input
cout << "\nWhat is the cost of the item: ";
cin >> itemCost;
cout << "\nIs the item taxable (Please use Y for Yes): ";
cin >> taxable;
//Adds the item cost to either the taxable or nontaxable variables
if (taxable == 'Y'){
totalTaxable += itemCost;
cout << "true";
} else{
totalNontaxable += itemCost;
cout <<"false";
}
itemCount -= 1;
}
total = (totalTaxable * (1 + (taxPercent / 100))) + totalNontaxable;
cout << "\n--------------------------------------------------\n";
cout << "You must earn $";
cout << total;
cout << " to meet this budget\n\n";
}