Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
I am writing a program to calculate the grade of 3 test scores. The lowest of the first 2 scores is dropped and added to the third test score to make the final grade. The 3 test scores cannot be higer than 50, lower than 0 and cannot be a character or string. So far, I have satisified all those requirment but I need to implement decimal grades to the program like for instance 45.5. Also to round the final grade up or down. For example if final grade is 89.5 round up to an A.
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
char getGrade(int num) {
if (num < 60)
return 'F';
if (num < 69)
return 'D';
if (num < 79)
return 'C';
if (num < 89)
return 'B';
return 'A';
}
bool isnumeric(string temp) {
for (char &chr : temp) {
if ((chr >= '0' and chr <= '9') or chr == '-')
continue;
else
return false;
}
return true;
}
int main(int argc, char const *argv[]) {
cout << "Welcome to the grade calculator.You will input three test "
"scores.\nThe highest of the first two grades and the third grade "
"will be\nadded together to determine the numeric grade average for "
"the\ncourse.Each test score has a maximum of 50 points.\n";
int arr[3];
int ctr = 0;
string temp;
int num;
while (ctr < 3) {
cout << "\nPlease enter test score " << (ctr + 1) << ": ";
label1:
cin >> temp;
if (isnumeric(temp)) {
num = atoi(temp.c_str());
if (num > 50) {
cout << "\nTest scores cannot be higher than 50, try again: ";
goto label1;
} else if (num < 0) {
cout << "\nTest scores cannot be negative, try again: ";
goto label1;
} else {
arr[ctr++] = num;
}
} else {
cout << "\nInvalid test score entered, try again: ";
goto label1;
}
}
int average = 0;
average = max(arr[0], arr[1]);
average = average + arr[2];
cout << "\nThe average for the course = " << average << "\n";
cout << "The letter grade = " << getGrade(average);
cout << "\n\n\nThank you for using this program\n";
return 0;
}
Just changed a couple of things to make it work with decimals:
1. Added chr == '.' to the isNumeric() function:
bool isnumeric(string temp) {
for (char& chr : temp) {
if ((chr >= '0' and chr <= '9') or chr == '-' or chr == '.')
continue;
else return false;
}
return true;
}
2. Changed variable types:
double arr[3]{};
int ctr = 0;
std::string temp;
double num;
3. Removed goto: (You can just use continue)
while (ctr < 3) {
std::cout << "\nPlease enter test score " << (ctr + 1) << ": ";
std::cin >> temp;
if (isnumeric(temp)) {
num = atof(temp.c_str());
if (num > 50) {
std::cout << "\nTest scores cannot be higher than 50, try again: ";
continue;
}
else if (num < 0) {
std::cout << "\nTest scores cannot be negative, try again: ";
continue;
}
else {
arr[ctr++] = num;
}
}
else {
std::cout << "\nInvalid test score entered, try again: ";
continue;
}
}
4. For rounding off, you can use std::round() as such:
double average = 0;
average = std::max(arr[0], arr[1]);
average = std::round(average + arr[2]);
You can also change your cout statements:
std::cout << "\nThe average for the course = " << average;
if (std::round(average) != average) std::cout << ", rounded off to = " << std::round(average);
std::cout << ".\nThe letter grade = " << getGrade(average);
std::cout << "\n\n\nThank you for using this program\n";
Just make all these changes and your program will successfully work with decimals.
Also, consider not using the following in your code:
using namespace std;
..as it's considered as a bad practice. For more info on why, look up to Why is using namespace std considered as a bad practice.
Edit: To accomplish your requirement, you can just change the while loop as such:
while (ctr < 3) {
if (temp.size() == 0)
{
std::cout << "\nPlease enter test score " << (ctr + 1) << ": ";
std::cin >> temp;
}
if (isnumeric(temp)) {
num = atof(temp.c_str());
if (num > 50) {
std::cout << "\nTest scores cannot be higher than 50, try again: ";
std::cin >> temp;
continue;
}
else if (num < 0) {
std::cout << "\nTest scores cannot be negative, try again: ";
std::cin >> temp;
continue;
}
else {
arr[ctr++] = num;
temp.clear();
}
}
else {
std::cout << "\nInvalid test score entered, try again: ";
std::cin >> temp;
continue;
}
}
The above code works as you said.
Related
Basically, this program allows a user to enter a sentence and depending on the users selection, it will show the middle character of the sentence, display it uppercase or lowercase, or backwards. Simple program, but I am new to programming so that may be the problem. I would like to figure out how to use loops instead of a ton of if statements. When I try to make some loops it breaks certain parts of the code but I am sure that is because I don't properly understand them. If you have any criticism or any advice on the code, I'd be happy to hear it. Thanks in advance!
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
int sel;
string sent;
bool validinput;
int i;
int x;
int j;
int a;
cout << "Welcome to my program. Enter a sentence and select one of the options below.\n";
cout << "Enter -999 to exit the program." << endl;
cout << "============================================================================" << endl;
cout << endl;
cout << "1. Display the middle character if there is one." << endl;
cout << "2. Convert to uppercase." << endl;
cout << "3. Convert to lowercase." << endl;
cout << "4. Display backwards." << endl;
cout << "Enter a sentence: ";
getline (cin, sent);
cout << "Selection: ";
cin >> sel;
if (sel < 1 && sel > 4)
{
cout << "Invalid input. Try again. Selection: ";
cin >> sel;
validinput = false;
}
else (sel >= 1 && sel <= 4);
{
validinput = true;
}
if (validinput == true)
{
if (sel == 1)
{
j = sent.length() / 2;
cout << "The middle character is: " << sent.at(j) << endl;
}
if (sel == 2)
{
for (int i = 0; i < sent.length(); i++)
{
if (sent.at(i) >= 'a' && sent.at(i) <= 'z')
{
sent.at(i) = sent.at(i) - 'a' + 'A';
}
}
cout << "Uppercase: " << sent << endl;
}
if (sel == 3)
{
for (int x = 0; x < sent.length(); x++)
{
if (sent.at(x) >= 'A' && sent.at(x) <= 'Z')
{
sent.at(x) = sent.at(x) - 'A' + 'a';
}
}
cout << "Lowercase: " << sent << endl;
}
if (sel == 4)
{
for (a = sent.length() - 1; a >= 0; a--)
{
cout << sent.at(a);
}
}
}
system("pause");
return 0;
}
Personally I would use the switch selection statement. I roughly did this just to explain a bit on how it can make your code more friendly and understandable.
int sel;
bool validInput = false;
switch(sel)
{
case 1:
//display middle char if there's one
case 2:
//convert to uppercase
case 3:
//convert to lowercase
case 4:
//display backwards
validInput = true;
break;
default: //if number does not meat 1, 2, 3 or 4
validInput = false;
break;
}
As you may notice, for case 1, case 2, case 3 and case 4, there's a break just to say that if the number is between 1 to 4; validInput is true.
Reference: Switch Selection Statement
i suggest using a switch. It will organize your code better. From looking at your code you seem to have used for and if wisely. But I suggest the if statements checking for the input be replaced with switch.
I have a small problem. I have attempted to make the game 'Word Jumble' with a scoring system. But sometimes, when the computer guesses a word, then it'll say: The word is: blank here. There should be a jumbled word there. When I try any word, it just subtracts 1.#INF points.
Code:
#include<iostream>
#include<string>
#include<stdlib.h>
#include<time.h>
using namespace std;
const int size=10;
string Words[size] = {
"consecutive",
"alternative",
"consequently",
"jumbled",
"computer",
"charger",
"food",//I'm hungry
"library",
"strawberry",
"carrier"
};
string Hints[size] = {
"Following continuously.",
"Something available as another opportunity.",
"As a result.",
"This word is rather jumbled, isn't it ;)",
"The enitiy you are reading this off of",
"My phone battery is running low",
"I'm hungry, I need some _",
"Where can I go get a book?",
"It's red, and not a berry."
"Either carries stuff, or is what your data company is called."
};
void main()
{
string word,hint;
double points=0;
bool correct=false,playAgain=true;
cout << "Welcome to Word Jumble!\n";
cout << "The objective of this game is to guess the jumbled word, correctly.\n";
cout << "Say 'quit' to quit, or 'hint' for a hint.\n";
while (playAgain==true)
{
correct = false;
int guesses = 0;
srand(static_cast<unsigned int>(time(0)));
int num = rand() % size + 1;
word = Words[num];
hint = Hints[num];
string jumble = word;
int length = jumble.size();
for (int i = 0; i < length*2; ++i)
{
int index1 = (rand() % length);
int index2 = (rand() % length);
char temp = jumble[index1];
jumble[index1] = jumble[index2];
jumble[index2] = temp;
}
cout << "The word is: " << jumble << endl;
double tempPoints=0;
while (correct==false)
{
string theGuess;
cout << "Guess the word: ";
cin >> theGuess;
guesses++;
while (!cin)
{
cin.sync();
cin.clear();
cout << "Ivalid entry, try again: ";
cin >> theGuess;
}
if (theGuess == word)
{
cout << "Correct! You guessed the word in only " << guesses << " tries!\n";
tempPoints += jumble.size()*1.5;
tempPoints -= (guesses - 1) / 4.0;
points += tempPoints;
cout << "You have been awarded " << tempPoints << " points this round for a total of " << points << "!\n";
correct = true;
cout << "Would you like to play again? (y or n): ";
char tempYN;
cin >> tempYN;
while (!cin || tempYN != 'y' && tempYN != 'n')
{
cin.sync();
cin.clear();
cout << "Invalid entry.\nWould you like to play again? (y or n): ";
cin >> tempYN;
}
if (tempYN == 'y')
{
playAgain = true;
}
else
{
playAgain = false;
}
}
else if (theGuess == "hint")
{
tempPoints -= (1.0 / (jumble.size())) * 40;
cout << "Hint: " << hint << endl;
correct = false;
playAgain = true;
}
else if (theGuess == "quit")
{
correct = true;
playAgain = false;
}
else
{
double sub = (1.0 / (jumble.size())) * 20;
cout << "Incorrect word, deducting "<<sub<<" points\n";
tempPoints -= sub;
playAgain = true;
correct = false;
}
};
};
cout << "Goodbye\n";
}
In the line:
int num = rand() % size + 1;
You are saying to select a random number between 0 and 9 then add 1.
If the random number is 9 the + 1 will make it 10. This means that you are trying to access a value in the array Words and Hints at index 10. Since arrays are 0 indexed and it's size is 10 that means you only have elements at 0 - 9.
You also will never get the first string in the arrays.
I'm trying to get the program to loop again, up to three times, if the user entered a number that does not follow the function defined in the if statement. The code as is, only loops once and then exits. Did I type the for loop incorrectly or is it the if...else statement that is wrong?
#include <iostream>
using std::cout; using std::cin; using std::endl;
int main() {
cout << "Enter a positive odd number less than 40: ";
int num = 0;
for (int a = 0; a < 3; ++a);
cin >> num;
{
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
}
else cout << "That is incorrect, try again!" << endl;
}
}
Did I type the for loop incorrectly or is it the if...else statement that is wrong?
Both. You should (1) remove the semicolon following the for statment; (2) move cin >> num into the for loop body; (3) add break; inside the if.
for (int a = 0; a < 3; ++a)
{
cin >> num;
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
break;
}
else cout << "That is incorrect, try again!" << endl;
}
BTW1: Try to use the debugger, then you'll find out what happened in fact.
BTW2: The code will fail when cin >> num fails (e.g. user entered an invalid value), you might need to check the result of cin >> num, to process the case. Such as:
for (int a = 0; a < 3; ++a)
{
if (cin >> num)
{
if (num < 40 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl;
break;
}
else cout << "That is incorrect, try again!" << endl;
}
else
{
cin.clear(); // unset failbit
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip bad input
cout << "Wrong input, try again!" << endl;
}
}
bool isValid = false;
int num;
while(!isValid)
{
cout << "enter a positive odd integer " << endl;
cin >> num;
if(num < 40 && num > 0 && num % 2 == 1 )
{
cout << "thank you"<<endl;
isValid = true;
}
else
isValid = false;
}
Why not use some thing like this, it will loop until isValid = true which will only happen when your conditions are met?
I understand I guess, if you're doing a school project or some thing and you're forced to do it with a for loop but in general this would be a much better solution for some thing like this than a for loop!
I made a game where the player types in the scrambled word. Take for example, I have the word 'wall' which is then jumbled up to saying wlal. For a correct answer I multiply the length of the given word to the user by 1000, then report the score at the end.
However, I also have a hint feature set up, so when they type in hint they get a hint. As a penalty, I'd like it so the user get's their score cut in half. Also, if the player answers incorrectly, there is a 1000 point reduction to the score.
My program always sets the score to 0. What's the problem here.
EDITED CODE:
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <unistd.h>
using namespace std;
int main()
{
enum fields {WORD, HINT, NUM_FIELDS};
const int NUM_WORDS = 5;
const string WORDS[NUM_WORDS][NUM_FIELDS] = //5x2 array
{
{"wall", "Do you feel you're banging your head against something?"},
{"glasses", "These might help you see the answer."},
{"labored", "Going slowly, is it"},
{"persistent", "Keep at it."},
{"jumble", "It's what the game is all about."}
};
srand(static_cast<unsigned int>(time(0)));
int choice = rand() % NUM_WORDS;
//Choice value in array, than area in array where word and hint are
string theWord = WORDS[choice][WORD]; //word to guess
string theHint = WORDS[choice][HINT]; //hint for word
string jumble = theWord; //jumbled version of word
int length = jumble.size();
//Index1 and index2 are random locations in the string theWord
//last two lines swaps areas, ending the for function with a different
//jumble variable every time.
for (int i = 0; i < length; ++i)
{
int index1 = rand() % length;
int index2 = rand() % length;
char temp = jumble[index1];
jumble[index1] = jumble[index2];
jumble[index2] = temp;
}
cout << "\t\tWelcome to Word Jumble!\n\n";
cout << "Unscramble the letters to make a word.\n";
cout << "\n\n\nReady? (y/n)";
//I'm asking here if the player is ready
string isready;
cin >> isready;
if ((isready == "y") || (isready == "Y"))
{
cout << "Ok this is how the scoring works\n";
cout << "The length of the word you will guess is times by 5000.\n";
cout << "If you ask for a hint, your score will go down by half.\n";
cout << "If you get the wrong answer, your score will go down by 1000.";
cout << "\nOk, lets start!\n";
int counter = 3;
for(int i = 0; i < 3; ++i)
{
sleep(1);
cout << counter << "..." << endl;
counter--;
}
sleep(1);
}
else
{
cout << endl;
return 0;
}
cout << "Enter 'quit' to quit the game.\n";
cout << "Enter 'hint' for a hint.\n";
cout << "The jumble is: " << jumble;
//Score system
double score;
double amount_of_guesses, amount_of_wrong = 0;
string guess;
cout << "\n\nYour guess: ";
cin >> guess;
double wrong = 0;
while ((guess != theWord) && (guess != "quit"))
{
if (guess == "hint")
{
cout << theHint;
amount_of_guesses++;
}
else if (guess != theWord)
{
cout << "Sorry, that's not it.";
wrong++;
}
cout << "\n\nYour guess: ";
cin >> guess;
}
if (guess == theWord)
{
score = (theWord.length() * 1000);
}
if (amount_of_guesses != 0)
{
score = score / (amount_of_guesses * 2);
}
if( wrong != 0)
{
score = score - (wrong * 1000);
}
cout << "Your score is: " << score;
cout << "\nThanks for playing.\n";
return 0;
}
Your code works fine for me when double amount_of_guesses, amount_of_wrong = 0; is changed as: double amount_of_guesses=0; double amount_of_wrong = 0;
Additionally, the code score = score / (amount_of_guesses * 2); does not correctly penalize the player by cutting his or her score in half each time they ask for a hint.
You could replace that line with the following code segment to correctly penalize by cutting the score in half every time:
if (amount_of_guesses != 0)
{ while(amount_of_guesses!=0)
{
score = (score / 2);
amount_of_guesses--;
}
}
The code
int amount_of_guesses, amount_of_wrong = 0;
does not initialize amount_of_guesses to 0. It is likely to be a huge number since it will be what is in memory when program is running. If score is lower than amount_of_guesses, result will be 0 using integer division.
I believe the issue is that you never initialize amount_of_guesses. This declaration
int amount_of_guesses, amount_of_wrong = 0;
initializes amount_of_wrong to 0, but amount_of_guesses will just hold some random value that depends on what happens to be in memory. If that's a large value, then this:
if (amount_of_guesses != 0)
{
score = score / (amount_of_guesses * 2);
}
will end up making score == 0 (note that since score is an integer score / (amount_of_guesses * 2) ends up being the floor of that division)
I am encountering a logical error with this app. It is a word jumble app that displays a jumbled word and asks the player if he/she would like to play again once they guess correctly.
When I tell the app I do not want to play again it continues through the sequence anyway. I have a feeling that its bad nesting on my part.
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
enum fields {WORD, HINT, NUM_FIELDS};
const int NUM_WORDS = 5;
const string WORDS[NUM_WORDS][NUM_FIELDS] =
{
{"wall", "Are you banging your head against something?"},
{"jumble", "Its what this game is all about."},
{"glasses", "You might need these to read this text."},
{"labored", "Going slowly, is it?"},
{"persistent", "Keep at it."},
};
srand(static_cast<unsigned int>(time(0)));
cout << "\t\tWelcome to Word Jumble!\n\n";
cout << "Unscramble the the letters to make the word!\n";
cout << "Enter 'hint' for a hint\n";
cout << "Enter 'quit' to quit the game\n\n";
const int MAX_LEVEL = NUM_WORDS - 1;
int totalScore = 0;
for (int level = 0; level <= MAX_LEVEL; ++level)
{
string theWord = WORDS[level][WORD]; // Word to guess
string theHint = WORDS[level][HINT]; // Word hint
char playAgain;
string jumble = theWord; //Jumbled version of the word
int length = jumble.size();
int score = jumble.size() * 10;
for (int i = 0; i < length; ++i)
{
int index1 = (rand() % length);
int index2 = (rand() % length);
char temp = jumble[index1];
jumble[index1] = jumble[index2];
jumble[index2] = temp;
}
cout << jumble << endl;
string guess;
cout << "\nYour Guess: ";
cin >> guess;
while ((guess != theWord) && (guess != "quit"))
{
if (guess == "hint")
{
cout << theHint;
score = score / 2;
}
else
{
cout << "\n\nSorry thats not it.\n\n";
}
cout << "\n\nYour Guess: \n\n";
cin >> guess;
}
if (guess == theWord)
{
cout << "Thats it! You guessed it!\tYou scored: " << score << "\n\n";
cout << "Would you like to play again? (y/n): ";
cin >> playAgain;
if (playAgain = 'y')
{
continue;
}
else if (playAgain = 'n')
{
cout << "Your total score is: " << totalScore << endl;
break;
}
}
else if (guess == "quit")
{
if (totalScore > 0)
{
cout << "Your total score is: " << totalScore << endl;
}
break;
}
}
cout << "\nGoodbye.";
return 0;
}
When comparing playAgain to 'y' and 'n', you only have one equals sign, causing the first one ('y') to always execute instead of it being an actual choice, since the value of 'y' is not 0.
To fix this, they should be:
if (playAgain == 'y') //note ==
{
continue;
}
else if (playAgain == 'n') //note ==
{
cout << "Your total score is: " << totalScore << endl;
break;
}
Also, any sane (more modern) compiler should warn you about this if you have warnings turned on. Be sure to turn those on and take heed of them.
I think you will need == for your playAgain question. I often make mistakes with that.