I'm figuring out how to loop my code and now it got me confused, any help would be much appreciated, im a beginner here so please don't scold me.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
char ans;
cout << "CONVERSION\n\n";
cout << "Base 11 to Decimal\n";
a:cout << "Base 11: ";
getline(std::cin, str);
const auto bad_loc = str.find_first_not_of("0123456789aA");
if (bad_loc != std::string::npos)
{
std::cerr << "Invalid Input\n";
goto a;
}
unsigned long ul = std::stoul(str, nullptr, 11);
cout << "Decimal: " << ul << "\n\n";
cout << "Do you want to continue (Y/N)? ";
cin >> ans;
if (ans == 'y')
{
goto a;
}
else if (ans == 'n')
{
cout <<"Name:\tXXXXXXXX\n";
cout <<"Course:\tXXXXXXXX";
cout <<"Section:\tXXXXXXXX\n";
cout <<"Schedule:\tXXXXXXXX\n";
cout <<"Professor:\tXXXXXXXX\n";
}
return 0;
}
the output should be like this
CONVERSION
Base 11 to Decimal
Base 11: B
Invalid Input!
Base 11: A
//blank
Do you want to continue (Y/N)? X
Invalid Answer! (Y/N)? Y
//blank
Base11:
My problems are
(1)The program stops after looping in "base11:" whenever i answer Y and (2)if I answer any letter from "Do you want..." the program will end. (3) How to fix this thing.
We beginners should help each other should not we?:)
The program can look something like the following
#include <iostream>
#include <string>
#include <limits>
int main()
{
std::cout << "CONVERSION\n\n";
std::cout << "Base 11 to Decimal\n";
char ans;
do
{
std::string s;
bool valid_input = false;
while ( !valid_input )
{
std::cout << "Base 11: ";
if ( !std::getline( std::cin, s ) ) break;
if ( !( valid_input = s.find_first_not_of( "0123456789aA" ) == std::string::npos ) )
{
std::cout << "Invalid Input\n\n";
}
}
if ( !valid_input )
{
std::cout << "See you later!" << std::endl;
break;
}
unsigned long value = std::stoul( s, nullptr, 11 );
std::cout << "Decimal: " << value << "\n\n";
std::cout << "Do you want to continue (Y/N)? ";
std::cin >> ans;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
} while ( ans == 'y' || ans == 'Y' );
std::cout <<"Name:\tXXXXXXXX\n";
std::cout <<"Course:\tXXXXXXXX";
std::cout <<"Section:\tXXXXXXXX\n";
std::cout <<"Schedule:\tXXXXXXXX\n";
std::cout <<"Professor:\tXXXXXXXX\n";
return 0;
}
If the input looks like
B
A
Y
C
AA
N
then the output will be
CONVERSION
Base 11 to Decimal
Base 11: B
Invalid Input
Base 11: A
Decimal: 10
Do you want to continue (Y/N)? Y
Base 11: C
Invalid Input
Base 11: AA
Decimal: 120
Do you want to continue (Y/N)? N
Name: XXXXXXXX
Course: XXXXXXXXSection: XXXXXXXX
Schedule: XXXXXXXX
Professor: XXXXXXXX
Pay attention to statement
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
that skips the new line character entered after inputting ans using operator >>.
bool run_attempt() {
get some input
if (bad input)
return false;
else {
do something good with the input
return true;
}
}
void main() {
bool success = false;
while (!success) {
success = run_attempt();
}
}
Related
I'm working through a text book for self study. I can do the while loop no problem, but I have no idea how to do the terminating character.
Here is what I have now:
#include "../../std_lib_facilities.h" // Supplied by book author
int main()
{
int ii = 0;
int yy = 0;
bool test = true;
cout << "Enter two ints" << endl;
while (test)
{
cin>>ii, cin>>yy;
// this if statement doesn't work
if (ii == '|' || yy == '|')
{
test = false;
}
// this if statement catches all bad input, even the terminating '|'
if (cin.fail())
{
cout << "bad input";
cin.clear();
cin.ignore();
continue;
}
else
cout << ii << yy << endl;
}
return 0;
}
Streams can be a little confusing if you're unfamiliar with them. It's a large topic that's just going to require more research. Here's an example that should work, to hopefully get you started.
int main(int argc, char* argv[])
{
bool test = true;
while ( test ) {
std::cout << "Enter two integers> ";
int x, y;
// if this fails, stream is bad.
// #note this will fail for any input which cannot be interpreted
// as an integer value.
if (std::cin >> x >> y) {
std::cout << x << " " << y << std::endl;
}
else {
// clear stream error state so we can read from it again.
std::cin.clear();
// check for terminating character; else unknown.
if (std::cin.get() == '|')
std::cout << "Terminator found, exiting." << std::endl;
else
std::cerr << "Error: bad input, exiting." << std::endl;
// in either case the loop terminates.
test = false;
}
}
return 0;
}
Hope this helps. Good luck.
Use the cin.peek() function as follows, before you input the two numbers:
c=(cin >> ws).peek();
if(c=='|')
{
cout<<"exiting";return 1;
}
Note: (cin>>ws) is to get rid of leading whitespaces. Also, c is of type char.
The complete code now looks like this:
int main()
{
int ii = 0;
int yy = 0;
bool test = true;
cout << "Enter two ints" << endl;
while (test)
{
char c;
c=(cin >> ws).peek();
if(c=='|')
{
cout<<"exiting";return 1;
}
cin>>ii, cin>>yy;
if (cin.fail())
{
cout << "bad input";
cin.clear();
cin.ignore();
continue;
}
else
cout << ii << yy << endl;
}
return 0;
}
I'm new to C++. I have errors. But, i dont know how to fix it. Could anyone please help me? Thank you.
P - Print numbers
A - Add a number
M - Display mean of the numbers
S - Display the smallest number
L - Display the largest number
Q - Quit
Errors : expected unqualified id before return 0
error : expected ';' before {}
#include <iostream>
#include <vector>
using namespace std;
int main(){
char input {};
vector <double> numbers {};
int number{};
int sum{};
int min_number{};
int max_number{};
bool condition {true};
cout << "Enter a command" << endl;
cin >> input;
if(numbers.size() > 0){
while(condition){
if (input == 'P' || input == 'p'){
for(auto x: numbers)
cout << x << endl;
}
else if(input == 'A' || input == 'a'){
cout << "Enter a number";
cin >> number;
numbers.push_back(number);
}
else if(input == 'M' || input == 'm'){
for(auto x : numbers)
sum += x;
cout << sum / numbers.size() << endl;
}
else if(input =='S' || input == 's'){
for(size_t i {0}; i < numbers.size(); ++i)
if(numbers.at(i) < min_number)
min_number =numbers.at(i);
}
else if(input =='L' || input == 'l'){
for(size_t i {0}; i < numbers.size(); ++i)
if(numbers.at(i) > max_number)
max_number =numbers.at(i);
}
else if(input =='Q' || input == 'q'){
condition {false};
}
}
cout << "[] - list is empty, unable to calculate" << endl;
}
return 0;
}
In your section dealing with Q/q, the statement:
condition {false};
is not a valid form of assignment, you should instead use:
condition = false;
The braces are fine for initialisation, but that's not what you're trying to do on that line.
As an aside, this line:
if(numbers.size() > 0){
seems a little strange. Since you initialise the list to empty, the main loop will never start (because it's inside the if block) even though you have already asked the user for input.
That's a runtime error rather than a syntax error but you'll still need to fix it at some point.
I suspect that particular should should be done only as part of the calculation of the mean, so as to avoid dividing by zero.
I have written this for you. Since, you're a learner, I think that you should be practicing better things like STL functions and not using using namespace std; at top.
You may find some things new, but don't be frightened, just search them on some website like cppreference and see what that entity do and how to effectively use it.
There were many logical errors. #paxdiablo has mentioned them in his answer. I have removed every of them and this code works.
#include <algorithm>
#include <cctype>
#include <iostream>
#include <vector>
int main() {
std::vector<double> numbers;
while (true) {
char input;
std::cout << "Enter a command: ";
std::cin >> input;
switch (std::toupper(input)) {
case 'P':
if (numbers.empty())
std::cerr << "The list is empty!" << std::endl;
else {
for (auto &&i : numbers)
std::cout << i << ' ';
std::cout << std::endl;
}
break;
case 'A': {
int number;
std::cout << "Enter a number: ";
std::cin >> number;
numbers.push_back(number);
break;
}
case 'M':
if (numbers.empty())
std::cerr << "The list is empty! Cannot perform the operation!!";
else {
int sum = 0;
for (auto &&i : numbers)
sum += i;
std::cout << "Mean: " << (sum / numbers.size()) << std::endl;
}
break;
case 'S':
std::cout << "Smallest Number: " << *std::min_element(numbers.begin(), numbers.end()) << std::endl;
break;
case 'L':
std::cout << "Largest Number: " << *std::max_element(numbers.begin(), numbers.end()) << std::endl;
break;
case 'Q':
return 0;
default:
std::cerr << "Unrecognised Command!!" << std::endl;
}
}
return 0;
}
This is a program that grade user inputs for the questions of Driver's License Exam.
I'm having trouble of validating the user input.
I'd like to accept the [ENTER] key as an invalid input and proceed to my validation rather than just go to an empty line and cannot process to the next question. Purpose is to send out error message and that no input is given and [ENTER] key is not valid input and only accept one more chance to enter valid input which are a/A, b/B, c/C, or d/D. So that is why I'm using if statement here instead of loop.
I tried if (testTakerAnswers[ans] == (or =) '\n') {} but still doesn't solve the problem of newline.
I include curses.h in here hope to use getch() statement from the other post but somehow I can't manage to work in my code with an array instead of regular input.
I'm looking for other methods as well rather than getch()
So should I adjust my bool function, or directly validate input in main() function.
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
#include <curses.h>
using namespace std;
const unsigned SIZE = 20; // Number of qns in the test
char testTakerAnswers[SIZE]; //Array to hold test taker's answers
bool validateInput(char);
class TestGrader
{
private:
char answers[SIZE]; // Holds the correct answers // Answer is array
int getNumWrong (char[]);
void missedQuestions (char[]);
public:
void setKey(string); // Initialize object with standard keys
void grade(char[]); // Grades the answers from tester
};
void TestGrader::setKey(string key){
if (key.length()!=SIZE){
cout << "Error in key data.\n";
return;
}
for (unsigned pos = 0; pos < SIZE ; pos ++)
answers [pos] = key [pos];
}
void TestGrader::grade(char test[])
{
int numWrong = getNumWrong(test);
if (numWrong <= 5)
cout << "Congratulations. You passed the exam.\n";
else
cout << "You did not pass the exam. \n";
cout << "You got " << (SIZE-numWrong) << " questions correct. \n";
if (numWrong > 0){
cout << "You missed the following " << numWrong << " questions: \n";
missedQuestions(test);
}
}
int TestGrader::getNumWrong(char test[])
{
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
counter++;
}
}
return counter;
}
void TestGrader::missedQuestions(char test[])
{
// cout << testTakerAnswers[i]; This is to print taker's answers
int counter = 0;
for (int i = 0; i < SIZE; i++){
if (answers[i] != toupper(testTakerAnswers[i])){
cout << "\n" << i + 1 << ". Correct answers: " << answers[i];
counter++;
}
}
}
bool validateInput(char ans){ // Only A, B, C, D valid input
if (toupper(ans)!='A' && toupper(ans)!= 'B' && toupper(ans)!='C' && toupper(ans)!= 'D'){
cout << "\n********************WARNING*******************\n";
cout << "Invalid input! Enter only a/A, b/B, c/C, or d/D\n";
return false;
}
if (testTakerAnswers[ans] == '\n'){
return false;
}
return true;
}
int main()
{
const int NUM_QUESTIONS = 20;
string name; //Test taker's name
char doAnother; //Control variable for main processing loop
TestGrader DMVexam; //Create a TestGrader object
DMVexam.setKey("BDAACABACDBCDADCCBDA");
do {
cout << "Applicant Name: ";
getline(cin,name);
cout << "Enter answer for " << name << ".\n";
cout << "Use only letters a/A, b/B, c/C, and d/D. \n\n";
for (int i = 0; i < NUM_QUESTIONS; i++){
// Input and validate it
do{
cout << "Q" << i+1 << ": ";
cin >> testTakerAnswers[i];
if (!validateInput(testTakerAnswers[i])){
cout << "You get one more chance to correct.\nOtherwise, it count as wrong answer.";
cout << "\n*********************************************";
cout << "\nRe-enter: ";
cin >> testTakerAnswers[i];
cout << '\n';
break;
}
}while(!validateInput(testTakerAnswers[i]));
}
//Call class function to grade the exam
cout << "Results for " << name << '\n';
DMVexam.grade(testTakerAnswers);
cout << "\nGrade another exam (Y/N)? ";
cin >> doAnother;
while (doAnother != 'Y' && doAnother != 'N' && doAnother != 'y' && doAnother != 'n'){
cout << doAnother << " is not a valid option. Try Again y/Y or n/N" << endl;
cin >> doAnother;}
cout << endl;
cin.ignore();
}while(doAnother != 'N' && doAnother != 'n');
return 0;
}
Your issue is cin >> testTakerAnswers[i]; cin is whitespace delimited, that means that any whitespace (including '\n') will be discarded. So testTakerAnswers[i] can never be '\n'.
I'm not sure exactly what you want to do, but possibly try
getline(cin,input_string);
then
input_string == "A" | input_string == "B" | ...
So if only the enter key is pressed, input_string will become "".
I'm trying to learn C++ and i cant figure a problem out.
My code:
#include <iostream>
using namespace std;
int userContinue = true;
int userContinueString;
int getUserInput() {
int userInput1;
int userInput2;
cout << "Please enter your first number: ";
cin >> userInput1;
cout << endl << "Please enter your second number: ";
cin >> userInput2;
cout << endl << "The result of the two numbers together: " << userInput1+userInput2;
userInput1 = 0;
userInput2 = 0;
return 0;
}
int main()
{
while (userContinue == true) {
getUserInput();
cout << endl << "Would you like to continue? (Y/N): ";
cin >> userContinueString;
if (userContinueString ='Y') {
}
else {
userContinue = false;
}
}
return 0;
}
The code works fine until i input "Y" ant then it keeps looping as shown here: Video
First, make sure you compile your code with some warning switches such as -Wall -Wpedantic. These switches will help you. For instance, in your original code, my compiler prints the following warnings:
prog.cpp:25:28: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
if (userContinueString = 'Y') {
~~~~~~~~~~~~~~~~~~~^~~~~
prog.cpp:25:28: note: place parentheses around the assignment to silence this warning
if (userContinueString = 'Y') {
^
( )
prog.cpp:25:28: note: use '==' to turn this assignment into an equality comparison
if (userContinueString = 'Y') {
^
==
1 warning generated.
Then, I fix the corresponding line with ==, which was already suggested in the comments. Then, your comparison should be case-insensitive. Finally, you would like to compare character objects with respect to 'y' or 'Y':
#include <cctype>
#include <iostream>
using namespace std;
int userContinue = true;
char /* not int */ userContinueString;
int getUserInput() {
int userInput1;
int userInput2;
cout << "Please enter your first number: ";
cin >> userInput1;
cout << endl << "Please enter your second number: ";
cin >> userInput2;
cout << endl
<< "The result of the two numbers together: " << userInput1 + userInput2;
userInput1 = 0;
userInput2 = 0;
return 0;
}
int main() {
while (userContinue == true) {
getUserInput();
cout << endl << "Would you like to continue? (Y/N): ";
cin >> userContinueString;
if (std::tolower(userContinueString) == 'y') {
} else {
userContinue = false;
}
}
return 0;
}
EDIT. I have improved the answer by taking into account David's comment below. Note the use of #include <cctype> and std::tolower.
EDIT. I have tried improving the answer further by trying to address the "learning C++" comment below:
#include <functional>
#include <iostream>
#include <sstream>
#include <string>
#include <type_traits>
template <class value_t,
typename std::enable_if<std::is_floating_point<value_t>::value,
int>::type = 0>
struct Calculator {
Calculator() = default;
explicit operator bool() {
while (true) {
std::cout << "Valid operations: +, -, *, /, 0 (exit)\n";
std::cout << "What would you like to do: ";
if (!getUserInput(operation)) {
std::cerr << "Wrong input for operation\n";
continue;
}
switch (operation) {
case '0':
return false;
case '+':
case '-':
case '*':
case '/':
break;
default:
std::cerr << "Wrong input for operation\n";
continue;
}
std::cout << "Please enter v1: ";
if (!getUserInput(v1)) {
std::cerr << "Wrong input for v1\n";
continue;
}
std::cout << "Please enter v2: ";
if (!getUserInput(v2)) {
std::cerr << "Wrong input for v2\n";
continue;
}
calculate();
return true;
}
}
friend std::ostream &operator<<(std::ostream &os, const Calculator &c) {
os << "v1 " << c.operation << " v2 = " << c.result;
return os;
}
private:
char operation;
value_t v1, v2, result;
std::string line;
void calculate() {
switch (operation) {
case '+':
return calculate(std::plus<value_t>{});
case '-':
return calculate(std::minus<value_t>{});
case '*':
return calculate(std::multiplies<value_t>{});
case '/':
return calculate(std::divides<value_t>{});
case '0':
return;
}
}
template <class Func> void calculate(Func &&f) { result = f(v1, v2); }
template <class T> bool getUserInput(T &t) {
std::cin >> line;
std::istringstream ss{line};
return (ss >> t) && (ss >> std::ws).eof();
}
};
int main() {
Calculator<double> c;
while (c)
std::cout << c << '\n';
return 0;
}
I'm working through a text book for self study. I can do the while loop no problem, but I have no idea how to do the terminating character.
Here is what I have now:
#include "../../std_lib_facilities.h" // Supplied by book author
int main()
{
int ii = 0;
int yy = 0;
bool test = true;
cout << "Enter two ints" << endl;
while (test)
{
cin>>ii, cin>>yy;
// this if statement doesn't work
if (ii == '|' || yy == '|')
{
test = false;
}
// this if statement catches all bad input, even the terminating '|'
if (cin.fail())
{
cout << "bad input";
cin.clear();
cin.ignore();
continue;
}
else
cout << ii << yy << endl;
}
return 0;
}
Streams can be a little confusing if you're unfamiliar with them. It's a large topic that's just going to require more research. Here's an example that should work, to hopefully get you started.
int main(int argc, char* argv[])
{
bool test = true;
while ( test ) {
std::cout << "Enter two integers> ";
int x, y;
// if this fails, stream is bad.
// #note this will fail for any input which cannot be interpreted
// as an integer value.
if (std::cin >> x >> y) {
std::cout << x << " " << y << std::endl;
}
else {
// clear stream error state so we can read from it again.
std::cin.clear();
// check for terminating character; else unknown.
if (std::cin.get() == '|')
std::cout << "Terminator found, exiting." << std::endl;
else
std::cerr << "Error: bad input, exiting." << std::endl;
// in either case the loop terminates.
test = false;
}
}
return 0;
}
Hope this helps. Good luck.
Use the cin.peek() function as follows, before you input the two numbers:
c=(cin >> ws).peek();
if(c=='|')
{
cout<<"exiting";return 1;
}
Note: (cin>>ws) is to get rid of leading whitespaces. Also, c is of type char.
The complete code now looks like this:
int main()
{
int ii = 0;
int yy = 0;
bool test = true;
cout << "Enter two ints" << endl;
while (test)
{
char c;
c=(cin >> ws).peek();
if(c=='|')
{
cout<<"exiting";return 1;
}
cin>>ii, cin>>yy;
if (cin.fail())
{
cout << "bad input";
cin.clear();
cin.ignore();
continue;
}
else
cout << ii << yy << endl;
}
return 0;
}