GPA rater in C++ - c++

I'm trying to code a GPA rater.
The problem:
Write a C++ program that asks the user for their cumulative GPA in the range [0,4]. If the GPAenter code here
is in:
[3-4] you say, “Superb!”
[2-3[ you say, “Good!”
[1-2[ you say, “Hmm!”
[0-1[ you say, “No comment!”
The program should display an error message and exit if the GPA entered exceeds 4 or less than
0.
Code:
#include <iostream>
using namespace std;
int main()
{
double grade;
cout << "Input your GPA: ";
cin >> grade;
cout << endl << endl;
if (grade >= 0 && grade <= 4)
{
if (grade >= 0 && grade <= 1)
{
cout << "No comment!";
}
if (grade >= 1 && grade <= 2)
{
cout << "Hmm!";
}
if (grade >= 2 && grade <= 3)
{
cout << "Good!";
}
if (grade >= 3 && grade <= 4)
{
cout << "Superb!";
}
}
else
{
cout << "Error : GPA is not in the specified range";
}
return 0;
}
I feel there is a more efficient way than mine.
Is there?
Thanks in advance

There's probably a way to code golf it, but your code is clear. It does check things that you already know more than once.
For example, if (grade >= 0), then it still is on the next line. If it's not <= 1, then it is definitely > 1 -- you only need to check if it's <= 2 (with else if).
If you want to make something silly, you could something like this (after checking if grade is in range):
string m[4] = {"No comment!", "Hmm!", "Good!", "Superb!"};
cout << m[min(3, int(grade))];
You need to add:
#include <cmath>
#include <string>
It's fewer lines of code, but possibly not more efficient (you need to measure)

Related

Need help defining a Loop Control Variable (while loops) C++

I have been trying forever to figure out what loop control variable (LCV) to use for my program to work but I have been unsuccessful.
The information given is as follows:
You will be promoting a student for grades and credits for courses taken. From that, you will calculate a GPA.
The course name is prompted for, but nothing is done with it.
We are just using the grades A, B, C, D, and F so you won't have to do so much typing!
You will need to use the "set precision" command as shown in the book. Set it to "fixed" and "2".
You will need to use the "cin.ignore()" function as discussed earlier in the course.
Notes
I used int total to count the number of classes.
Current while statement was my last attempt, and it is not correct.
My code:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main () {
cout << std::fixed << std::setprecision(2);
string course, grade, answer;
int credits, total = 0;
float gradePoints = 0, totalCredits = 0;
float gpa = 0.0;
while (grade <= "ABC") {
cout << "Enter a course name: ";
getline(cin, course);
cout << course << endl;
cout << "Enter number of credits: ";
cin >> credits;
cout << credits << endl;
cout << "Enter your grade (A, B, C, D, F): ";
cin >> grade;
cout << grade << endl;
cout << "Continue ('Yes' or 'No')? ";
cin >> answer;
cout << answer << endl;
if (grade == "A") {
gradePoints = gradePoints + 4;
}
else if (grade == "B") {
gradePoints == gradePoints + 3;
}
else if (grade == "C") {
gradePoints = gradePoints + 2;
}
else if (grade == "D") {
gradePoints = gradePoints + 1;
}
else if (grade == "F") {
gradePoints = 0;
}
total = total + 1;
totalCredits = totalCredits + credits;
}
gpa = (total * gradePoints)/ totalCredits;
return 0;
}
Based on the way the rest of the program is written, I'd think that you'd want to check against the user's response to the "Continue?" question. Something like this:
bool answer = true;
while (answer) {
// code
// when ready to exit...
answer = false;
}
That said, it might make more sense to use a do-while loop, where the first block executes before the conditional is checked:
do {
// code
} while (answer != "No");
And while you're at it, you might also want to consider using a different flag than having the user type in "Yes" or "No". Something like y and n is more common and a bit simpler.
"while (grade <= "ABC")"
If the intent is to say only do the loop while grade has a value of A, or B, or C, then:
while(grade == "A" || grade == "B" || grade == "C")

C++ Visual Studio : Debug Assertion Failed! Expression: c >= -1 && c <= 255

I'm trying to do a basic C++ score / grade system. I want to validate the users input. If the data is not a number, I want it to display an error message. If it is, I want it to carry on.
However, if the user enters a letter, say for example 'a' or 'A'. It spits out this error :
Debug Assertion Failed!
Program:
...ers\Alex\source\repos\worksheet_1.2a\Debug\worksheet_1.2a.exe
File: minkernel\crts\ucrt\appcrt\convert\isctype.cpp
Line: 36
Expression: c >= -1 && c <= 255
This is the code:
#include "stdafx.h"
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
int score;
// Recieve user input of score between 0-100. Stores input in score var
cout << "\nWhat score did you get?\n" << endl;
cin >> score;
// Validating input
if (!isdigit(score)) {
if (score <= 59)
cout << "Your grade is F" << endl;
else if (score > 59 && score < 70)
cout << "Your grade is D" << endl;
else if (score > 69 && score < 80)
cout << "Your grade is C" << endl;
else if (score > 79 && score < 90)
cout << "Your grade is B" << endl;
else if (score > 89)
cout << "Your grade is A" << endl;
}
else {
cout << "Sorry, that is not a number. Please try again." << endl;
}
return 0;
}
It works fine if a number is entered, but not at all if a letter is.
I have looked at several other answers and videos based on 'Debug Assertion Failed' but cannot find one for this particular error.
Thanks for reading and help given!
It is rather strange that isdigit takes an int not a char, because thats what it is for (from here, emphazise mine):
Checks if the given character is one of the 10 decimal digits:
0123456789.
The behavior is undefined if the value of ch is not representable as
unsigned char and is not equal to EOF.
Seems like isdigit is quite some trap and you were lucky to get assertion fired. Anyhow, even though it takes an int you should pass a char:
std::string s = "12asbc";
std::cout << isdigit(s[0]); // prints 1
std::cout << isdigit(s[3]); // prints 0
Anyhow your check isnt that meaningful. If it worked as you expected, you would only know that the number isnt a single digit, but your code would still fail if the user entered abcd or anything that is not a number. To check if the input was correct, you could do
int score;
if (std::cin >> score && 0 <= score && score <= 100) {
// ok input
} else {
// invalid input
}
why did you type !isdigit(score) instead of isdigit(score)?
Don't put ! in front of isdigit(score).
isdigit() returns True when the argument is number.

Grade program syntax issue

Good evening everyone, In attempting to write my grade code for class I seem to have come errors... Namely the operator after the && gives the error (expected an expression) and that the else statements give an error saying there is no if statement. Anyone care to help?
#include <iostream>
using namespace std;
int main()
{
double point;
cout << "Enter your grade point." << endl;
cin >> point;
if (point <= 100 && >= 90) {
cout << "Congratulations! You got an A" << endl;
}
else if (point >= 80 && < 90) {
cout << "Good Job, you got a B" << endl;
}
else if (point >= 70 && < 80) {
cout << "You got a C, at least it counts." << endl;
}
else if (point >= 60 && < 70)
{
cout << "You got a D... should have tried harder" << endl;
}
else if (point >= 0 && < 60)
{
cout << "You got an E. What happened?!?" << endl;
}
else if (point < 0 || >100)
{
cout << "Invalid input" << endl;
}
system("pause");
return 0;
}
Since I already explained what's wrong in the comment, I figured out that it might be helpful to write a full answer with additional hints.
Taking a second look at your problem: The expression if(point <= 100 && >= 90) is incorrect since the if statement expects a bool expression. Logical operator && determinates whether or not the left and right bool expressions are true and returns so if both indeed are. Pay attention to what you just read. Both expressions means that there is a need for two of them. The first one, being point <= 100 satisfies the requirements. However, the second one you provided is >= 90. This is not a valid expression, since you are expected to provide an indepented one. What you probably have in mind is check if 100 <= point <= 90. You have to separate it into two, independent expressions - if (point <= 100 && point >= 90) { // your code }
Additionally, I encourage you to read why using namespace std; is wrong.

Can't get function to work right. Extra numbers that shouldn't be displayed

I am new to C++ and programming in general so this is all difficult for me but I am really trying to learn. I can't get the letterGrade function to display correctly. I gives me the letter grade like it should but also adds a bunch of numbers after the letter grade. Could anyone please let me know what is going on and what I am doing wrong? Also I am supposed to use a function to find the average but I can only make it work by defining a variable sAverage in my "for" loop to display the array like a table. I had created a function for that as well but it didn't give me the right answer. Here is my code.
#include <cstdlib>
#include <iostream>
#include <iomanip>
using namespace std;
int letterGrade(int average)
{
if (average > 89)
cout << "A";
else if (average > 79 && average < 90)
cout << "B";
else if (average > 69 && average < 80)
cout << "C";
else if (average > 59 && average < 70)
cout << "D";
else if (average >= 0 && average < 60)
cout << "F";
}
void getInfo()
{
const int info = 2;
string last[info];
string first[info];
int ID[info];
int score1[info];
int score2[info];
int score3[info];
for (int count = 0; count < info; count++)
{
cout << "last name\n";
cin >> last[count];
cout << "first name\n";
cin >> first[count];
cout << "enter ID\n";
cin >> ID[count];
cout << "enter test 1\n";
cin >> score1[count];
cout << "enter test 2\n";
cin >> score2[count];
cout << "enter test 3\n";
cin >> score3[count];
}
cout << endl;
cout << "Last Name\tFirst Name\tID\tTest 1\tTest 2\tTest 3\tAverage\t Grade\n";
cout << "__________________________________________________________________\n";
for (int count = 0; count < info; count++)
{
int sAverage = ((score1[count]+score2[count]+score3[count])/3);
cout << setw(10) << last[count]
<< setw(10) << first[count]
<< setw(10) << ID[count]
<< setw(10) << score1[count]
<< setw(10) << score2[count]
<< setw(10) << score3[count]
<< setw(10) << sAverage
<< setw(10) << letterGrade(sAverage);
cout << endl;
}
}
int main(int argc, char *argv[])
{
cout << "Enter Student Info\n";
getInfo();
system("PAUSE");
return EXIT_SUCCESS;
}
The function I had to find the average was:
int getAverage(score1, score2, score3)
{
int average;
average = ((score1 + score2 + score3) / 3);
return average;
}
I called it like this
cout << getAverage(score1[info],score2[info],score3[info])
but it only came back with a high number in the hundreds but what I need is a function do average the scores in the array from the input.
Thanks in advance and again I am new to all this.
When you call the function:
cout << getAverage(score1[info],score2[info],score3[info])
where info is equal to 2, you're accessing memory out of bounds of the array. You're length of an array is 2, so the only valid indices are 0,1 - not 2.
Moreover, in the definition of function:
int getAverage(score1, score2, score3)
{
int average;
average = ((score1 + score2 + score3) / 3);
return average;
}
You didn't specify the types of scoreX variables, and the the implicit int rule is not valid in C++.
EDIT:
Another thing: when you're calculating the average, you have to remember that dividing an integer by an integer always gives an integer, so if you want to have more precise answer, e.g. for 2.66 2 3 3, you have to use a float.
Maybe you mis-read your output? The getAverage function should work correctly even though you didn't specify types for the parameters (they default to int, then).
It looks like your problem is a different one: your function letterGrade doesn't have a return statement, so it returns random junk. Your compiler should actually warn you about that. This junk is interpreted as a number (since you said the function is returning int) and formatted that way.
What you probably want is something like:
string letterGrade(int average)
{
if (average > 89)
return "A";
else if (average > 79 && average < 90)
return "B";
else if (average > 69 && average < 80)
return "C";
else if (average > 59 && average < 70)
return "D";
else if (average >= 0 && average < 60)
return "F";
else
return "-"; // negative value was passed!
}
You use << within a function without flushing cout. In fact, you say in the letterGrade prototype that you return an int but you don't, so when you call something like cout << letterGrade(...), it prints a random number
The protoype of letterGrade should rather be :
string letterGrade(int average)
and you must return your letter (using for example return "F"; instead of cout << "F").
It is often bad idea to print on the standard output without endl nor cout.fflush().

How do I stop a certain part of a program using the user's input?

I'm making a program that tallies grades. I want to know how to stop a certain part of a program based on the user's input. Below is the program I am working on. How do I stop the program if the user enters "done"? Also, I don't necessarily have to use "done" to exit the program. I was initially going to use -1, but I ran into a problem where I had to make a robust program where values < 0 and > 100 are not accepted.
int grade;
a=b=c=d=f=0;
do
{
cout << "Enter a grade or enter done to stop. ";
if (grade >= 90 && grade <= 100)
{a++;}
if (grade >= 80 && grade < 90)
{b++;}
if (grade >= 70 && grade < 80)
{c++;}
if (grade >= 60 && grade < 70)
{d++;}
if (grade >= 0 && grade < 60)
{f++;}
} while (grade != 'done');
just do a return 0? Also, you can't do grade = 'done', unless you overrode the = operator or something.
The most simple way to ask user to enter integer value, which is out of range of values you expected him to enter (ex. -1). "when done - enter -1".
Also if(grade = 'done') - assignement is here, to compare use operator==, which is
// if(grade == 'done')
or you can use the following approach:
do
{
cout << "Enter a grade or enter done to stop. ";
// first try to get string from user (which he/she enters when done)
string str;
cin >> str;
if (str == "done") // if done was entered - exit from the loop
break;
// else clear fail bit in stream object and read int value
cin.clear();
cin >> grade;
if (grade >= 90 && grade <= 100)
{//a++;}
if (grade >= 80 && grade < 90)
{//b++;}
if (grade >= 70 && grade < 80)
{//c++;}
if (grade >= 60 && grade < 70)
{//d++;}
if (grade >= 0 && grade < 60)
{//f++;}
} while (grade != 'done');
Firstly, "grade" is type int, so you can not convert int to *char, if you want that "grade" is int than you can exit with -1. Or if you want to exit with "done", than grade can be char[5], and you can use atoi() to convert string to integer to check, and strcmp() to compere "grade" with "done".
You have write code to enter a string. You can then test if the string equals "done". If it doesn't you then convert the string to an integer, then you can check against your grade boundaries.
If you really want to use numbers AND strings i suggest using stringstreams. Here is an example:
string Text = "456";//string containing the number
int Result;//number which will contain the result
stringstream convert(Text); // stringstream used for the conversion initialized with the contents of Text
if ( !(convert >> Result) )//give the value to Result using the characters in the string
Result = 0;//if that fails set Result to 0
//Result now equal to 456
Source link
First of all, single quotes denote a character literal, double quotes a null terminated string (2.14 or so).
if(grade = 'done') will always be true, compiler should have thrown a warning at you that you aren't doing what you think you are doing, you're assigning it then checking if it is true, which it will always be.
And you're trying to assign an integer to a string.
This seems like homework so i won't write it, but you need to take in a string from stdin, then parse it, e.g is it an integer or string, the act on that data. to terminate you can call exit, break from the loop or return from the function.
You can take the inputs as string, if the first character is not a digit then break the loop, covert the string to integer otherwise:
#include<iostream>
#include<string>
#include<cctype>
#include<cstdlib>
using namespace std;
int main() {
int grade;
string input;
int a, b, c, d, f;
a=b=c=d=f=0;
do
{
cout << "Enter a grade or enter done to stop: ";
cin >> input;
cout << endl;
if(!isdigit(input[0])) {
break;
} else {
grade = atoi(input.c_str());
}
if (grade >= 90 && grade <= 100)
{a++;}
if (grade >= 80 && grade < 90)
{b++;}
if (grade >= 70 && grade < 80)
{c++;}
if (grade >= 60 && grade < 70)
{d++;}
if (grade >= 0 && grade < 60)
{f++;}
} while (1==1);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
cout << "d = " << d << endl;
cout << "f = " << f << endl;
getchar();
return 0;
}