What am I doing Wrong with this C++ code? - c++

Sorry, forgot the code
Here is the incorrect code.
I have been trying to get this working, but all the logical operators do not work.
#include <iostream>
#include <string>
using namespace std;
string repeat;
string repeatnum;
string prompt = "|-[]->";
int main()
{
string entry;
bool Running = true;
while(Running == true)
{
cout << "\n";
cout << prompt;
cin >> entry;
if(entry == "Exit") return 0;
if(entry == "Help") cout << "HELP:\nThsi is a simple program, try an input";
if(entry == "ChangePrompt")
{
cout << "What do you want to change the prompt to?: ";
cin >> prompt;
}
if(entry == "Repeat" || "repeat")
{
cout << "What string do you want to repeat?: ";
cin >> repeat;
cout << "How many times do you want to repeat" << repeat << "(1-9)?: ";
cin >> repeatnum;
if(repeatnum > 0){}
}
}
char f;
cin >> f;
return 0;
}
Here is the error I am getting.
Error:
C:\Users\Packard Bell\Desktop\test\main.cpp||In function 'int main()':|
C:\Users\Packard Bell\Desktop\test\main.cpp|29|error: no match for 'operator>' in 'repeatnum > 0'|
||=== Build finished: 1 errors, 0 warnings ===|

Because at line 29 in main.cpp you attempt to do repeatnum > 0 and repeatnum is a type with no overloaded operator >.

In addition to the repeatnum problem, this piece of code isn't doing what you want
if(entry == "Repeat" || "repeat")
It should be
if(entry == "Repeat" || entry == "repeat")

From the given info, I can only guess that the variable repeatnum is an object of a class or structure which you cannot use to directly compare it with 0. If the type of repeatnum is defined by you, add a member function that overloads operator > and handle it properly.
class YourType
{
// Class definition
public:
int operator >( int var )
{
// Code for comparison
// return result
}
};

Now after seeing the code. repeatnum is a string. You read input to the string and then compare it with integer. Now string does not have operator>-defined for integer so you need to convert the string to integer before comparison.
atoi(repeatnum.c_str());
Or use stringstream to do it.

Related

Whats a good way to get the program to end based on user input?

I did my "Hello World", I'm just getting started on my programming adventure with C++. Here is the first thing I've written, what are some ways to get it to end with user input? I'd like a yes or no option that would terminate the program. Also any feedback is welcome, thank you
#include <iostream>
using namespace std;
void Welcome();
void calculateNum();
void tryAgain();
int main() {
Welcome();
while (true) {
calculateNum();
tryAgain();
}
system("pause");
}
void calculateNum() {
float userNumber;
cin >> userNumber;
for (int i = 100; i >= 1; i--) {
float cNumber = i* userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
}
void Welcome() {
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain() {
cout << "Try again? Enter another number... ";
}
Here is one option:
Switch to do ... while loop, with the condition at the end.
Make your tryAgain() function return a boolean and put it in the while condition.
In tryAgain function read input from the user, and compare it to expected answers.
First, lets add a new header for string, it will make some things easier:
#include <string>
Second, lets rebuild the loop:
do {
calculateNum();
} while (tryAgain());
And finally, lets modify the function:
bool tryAgain() {
string answer;
cout << "Try again? (yes / no)\n";
cin >> answer;
if (answer == "yes") return true;
return false;
}
Now, there is a slightly shorter way to write that return, but it might be confusing for new learners:
return answer == "yes";
You don't need the if because == is an operator that returns bool type value.
You can change your calculateNum() in the following way:
Change the return value of your calculateNum() function into bool to indicate whether the program shall continue or stop
read the input into a std::string
check if the string is equal to your exit string like 'q' for quit
3.a in that case, your function returns false to indicate the caller that the program shall stop
3.b otherwise, create a stringstream with your string and read the content of the stream into your float variable and continue as you do like now
In your loop in your main function you break if calculateNum() returned false
Here is a simple solution:
#include <iostream>
// Here are two new Includes!
#include <sstream>
#include <string>
using namespace std;
void Welcome();
// Change return value of calculateNum()
bool calculateNum();
void tryAgain();
int main()
{
Welcome();
while (true)
{
if (!calculateNum())
break;
tryAgain();
}
system("pause");
}
bool calculateNum()
{
//Read input into string
string userInput;
cin >> userInput;
//Check for quit - string - here just simple q
if (userInput == "q")
return false;
//otherwise use a std::stringstream to read the string into a float as done before from cin.
float userNumber;
stringstream ss(userInput);
ss >> userNumber;
//and proces your numbers as before
for (int i = 100; i >= 1; i--)
{
float cNumber = i * userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
return true;
}
void Welcome()
{
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain()
{
cout << "Try again? Enter another number... ";
}
Having your users input in a string you can even do further checks like checking if the user entered a valid number, interpret localized numbers like . and , for decimal delimitters depending on your system settings and so on.

Undefined behaviour when entering `char` for integer variable with `std::cin`

I have this while loop, just to check if the entered number is 2. If the user entered by accident a letter instead of a number the loop goes to infinity even though I've added isdigit, but didn't fix the loop from going crazy if the input is a character. This is code:
int num1;
bool cond {false};
while(!cond){
cout<<"enter 2:";
cin>>num1;
if (!isdigit(num1)){
cout<<"not a digit:";
cin>>num1;
}
//
if(num1 == 2)
cond = true;
}
I would suggest trying something a little more straightforward instead of your current code:
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int num1;
cout << "Please enter the number 2:";
cin >> num1;
while (num1 != 2)
{
cin.clear(); //Clears the error flag on cin.
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "You did not enter the number 2, Please try again:";
cin >> num1;
}
return 0;
}
Now, cin.ignore(numeric_limits<streamsize>::max(), '\n'); is when it ignores up until '\n' or EOF \n is the delimiter meaning that, that is the character at which cin will stop ignoring.
Furthermore, numeric_limits<streamsize>::max() is basically saying there is no limit to the number of characters to ignore.
You need to use the header file #include<limits> to use this.
I recommend separating the reading of input data from converting it to a number. A good method for this is to use stringstream. Here's a working example:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
int num1;
string input;
bool cond{ false };
cout << "enter 2:";
while (!cond) {
getline(cin, input);
stringstream ss(input);
ss >> num1;
if( ss.fail() ){
cout << "not a digit:";
continue;
}
//
if (num1 == 2)
cond = true;
else
cout << "enter 2:";
}
return 0;
}
int num1;
bool cond {false};
do{
cout<<"enter 2:";
cin>>num1;
if (cin.good()) {
cond = true;
}else {
cin.clear();
cin.ignore();
cout << "Invalid, please enter 2." << endl;
}
}while(!cond);
While false, execute statements. Also, if you want the user to re-enter a number, cin must be flushed.
Try declaring the variable num1 as char because isdigit(ch) works for char and not for int.
I hope this solves your problem
Why does the loop iterate infinitely?
Let's take this example
int a;
std::cin >> a;
std::cout << "Entered: " << a;
Now let's test it with different inputs
with int
5
Entered: 5
10
Entered: 10
Yes just as we would expect, but what happens when you enter a char?
with char
r
Entered: 0
f
Entered: 0
Why does this happen?
When you declare the variable int, and then do std::cin >> , you are telling the input method that the user will enter an integer, but when it doesn't get what it expected, it will fail. C++ will not implicitly convert the value of char into int. Hence, you get strange results.
How to solve this?
As I have mentioned earlier, it fails. When this fails you can catch it this way
if (!(std::cin >> a))
{
std::cout << "Invalid input ! \n";
}
We're saying, if the input fails, show the message.
let's test this new code.
int a;
if (!(std::cin >> a))
{
std::cout << "Invalid input !\n";
}
else
{
std::cout << "Entered: " << a;
}
5
Entered: 5
r
Invalid input !
How to print char value of the int?
If you want to just print the ASCII value of the entered number, you need to cast the value into char.
You can do
int num = 48;
char character_value = num;
Here C++ will implicitly convert char into int.
But if you need a safer type of conversion, prefer using static_cast<>.
The syntax looks like this
int a = 5;
char character_value = static_cast<char>(a);
Static cast in C++
Type casting in C++
Dealing with invalid input in C++

How to check if the input taken by the user doesn't contain decimal?

I am a newbie to C++. I have a situation where the input integer is taken from the user. However, I need to check if the user enters a decimal value. How do I check this?
I have tried cin.good(), cin.fail() but they are detecting only non-digit entries and not decimal numbers. Any help would be appreciated.
#include <iostream>
int main()
{
using namespace std;
int x;
cout << "Enter an integer: " << endl;
cin >> x;
if (cin.good()) {
cout << "input is an integer" << endl;
}
else
cout << "input is not an integer" << endl;
}
Here's my output:
1.
Enter an integer:
1.2
input is an integer
2.
Enter an integer:
a
input is not an integer
float x = 4.2;
if (x == (int) x)
{
// int
}
else
{
// not int
}
You can use std::isdigit for checking your string input next way.
bool is_numeric(const std::string& str)
{
std::string::const_iterator it = str.begin();
if (it != str.end() && *it == '-') ++it;
if (it == str.end()) return false;
while (it != str.end() && std::isdigit(*it)) ++it;
return it == str.end();
}
It's not hard to change it to work with floating points, if needs, but that function will exactly checks what you need.
You receive the input as an int from cin and hence any float entered would already be truncated by the time you get your hands on it. You should receive it as a float or a string to decide on the validity of the input.
Removed the earlier answer since it went down the slippery route of manually parsing the input which is unnecessary and error-prone. The standard library already has multiple ways to check if an input is a valid number. Two ways that I know: C++ streams and the C library function strtof. Here's an example using the latter:
#include <iostream>
#include <string>
#include <cmath>
bool is_int(float f) {
return std::floor(f) == f;
}
int main()
{
std::cout << "Enter an integer: ";
std::string input;
std::cin >> input;
char *e = nullptr;
char const *str = input.c_str();
float const f = strtof(str, &e);
// no conversion was performed or was stopped as disallowed
// characters were encountered: Not A Number
if ((e == str) || (*e != '\0'))
std::cout << "NAN";
else if ((f == HUGE_VALF) || !std::isfinite(f))
std::cout << "too large";
else
std::cout << (is_int(f) ? "integer" : "non-integer");
std::cout << '\n';
}
Live example.
To check if the input is a number, this
float f;
cin >> f;
is possible too, but it will also accept NANs as valid input e.g. 45dsf will be converted to 45. One has to then check if the conversion happened completely and successfully by checking the fail and eof bits of the stream.
See also
Checking if float is an integer
C++ IsFloat function
How to convert a number to string and vice versa in C++

Trying to acomplish a Loop determined by user input using "while (COM != "Y" || "N" )"

So the problem I am having is in my Class IOutro, and in it's function commandInput(), my intention was to create a simple command based loop, asking if the user would like to use the program again or close it.
My goal with this program was to use classes only to store functions, the only thing I wanted in main was objects calling those functions. Just a first try with OOP.
So, The error have been getting when I attempt to run this.
||=== Build: Debug in Tutorials (compiler: GNU GCC Compiler) ===|
C:\Users\Jason\Documents\Tutorials\main.cpp||In function 'int main()':|
C:\Users\Jason\Documents\Tutorials\main.cpp|57|error: could not convert 'COM.std::basic_string<_CharT, _Traits, _Alloc>::operator=<char, std::char_traits<char>, std::allocator<char> >(((const char*)"Y"))' from 'std::basic_string<char>' to 'bool'|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
I am not sure what I should be looking at, I am understanding it's a problem with my string I am using, it also gave me an error once, before some changes saying it could not identify != Operator, I was thinking that != means "Is Not Equal To" and || means "Or" (( Basically, if the left is NOT true, check the right value, if the LEFT value IS true, ignore the right value. ))
I am sure I am missing something simple, or maybe I am not looking up the right information. Can someone please enlighten me.
This is NOT for homework, I am not a student, I am self-teaching myself c++ and places like this are essentially my only place to find answers.
#include <iostream> // This is a PreProcessor Directive
#include <string> // Do I need this?
using namespace std; // This includes a library???
int A; // Global A
int B; // Global B
string COM = "Y"; // Global used to check if they want to keep going, not sure how to make this not global.
class Arith{ // Class for the calculator stuff.
public: // Class is public.
int sum(int A, int B){ // Sum, the actually calculation.
int C = A + B; // Just math.
return C; // Return value of C.
}
void calc(){ // Calc, not a calculation.
cout << "Enter a number for A: "; // Ask for A.
cin >> A; // Get A.
cout << endl; // Make it look neat.
cout << "Enter a number for B: "; // Ask for B.
cin >> B; // Get B.
cout << endl; // Make it look neat.
cout << "The sum is: " << sum(A, B); // Print out the sum.
}
};
class IOutro{ // Class for all informative prompts.
public:
void goodbye(){ // The goodbye class
cout << "Thank you!" << endl; // Display a goodbye.
}
void welcome(){ // The welcome class.
cout << "Welcome!" << endl; // Display a welcome.
}
void commandInput(){ // The FML check if they want to keep adding numbers loop of doom...
cout << "Would you like to continue?" << endl; // Goal is to check if they want to keep going, Y or N.
cout << "Please type 'Y' for Yes, and 'N' for No." << endl; // They are given options
cin >> COM; // ???? Get COM
while (COM != "Y" || "N" ){ // Trying to make it assure they type Y or N, and if they don't it keeps asking.
cout << "Would you like to continue?" << endl; // Copied the text.
cout << "Please type 'Y' for Yes, and 'N' for No." << endl; // For this loop.
cin >> COM; // ???? Get COM, I am pretty sure it's suppose to be getline, but that doesn't work...
}
}
};
int main(){ // Indicates a Main Function which returns an Integer?
IOutro IObject; // Declare the IOutro IObject Object?
Arith ArithObject; // Same with Arith?
while (COM = "Y"){ // If they chose Y, run loop
IObject.welcome(); // Run IObject welcome
ArithObject.calc(); // Run ArithObject calc
ArithObject.sum(A,B); // Run ArithObject sum
IObject.commandInput(); // Run IObject commandInput
}
IObject.goodbye(); // If COM != "Y" run IObject goodbye
return 0; // Return the value 0 to main?
}
Let's look at the problems in your code.
First, you don't need COM to be a string, it's more than enough to declare it as a char, like
char COM = 'Y';
Next, you should change the while loop condition in commandInput() from
while (COM != "Y" || "N" )
to
while (COM != 'Y' && COM != 'N' ) // if you don't want it to be case sensitive, then you will have to add small letters to the condition as well
Your condition is not right, you needed to check both like given above.
Now you might wonder why I changed the || to &&. This is because if it was ||, if COM is not 'Y' or COM is not 'N', the loop will continue. Now just think like this, if COM is 'Y', then it is not 'N', and if it is not 'N', then the condition in your while loop is satisfied, and hence, it just continues.
Now, lets look at the next problem. In your main(), you have
while (COM = "Y")
The = is the assignment operator, if you want to check for equality, then you need to use ==. That is
while (COM == 'Y' )
So in short, a fixed version of your code would be ( I've removed your comments and added comments where I have made changes, there are changes in three lines )
#include <iostream>
using namespace std;
int A;
int B;
char COM = 'Y'; // changed to char
class Arith{
public:
int sum(int A, int B){
int C = A + B;
return C;
}
void calc(){
cout << "Enter a number for A: ";
cin >> A;
cout << endl;
cout << "Enter a number for B: ";
cin >> B;
cout << endl;
cout << "The sum is: " << sum(A, B)<<endl;
}
};
class IOutro{
public:
void goodbye(){
cout << "Thank you!" << endl;
}
void welcome(){
cout << "Welcome!" << endl;
}
void commandInput(){
cout << "\nWould you like to continue?" << endl;
cout << "Please type 'Y' for Yes, and 'N' for No." << endl;
cin >> COM;
while ( ( COM != 'Y' && COM != 'y' ) && ( COM != 'N' && COM != 'n' ) ) { // made changes here
cout << "\nWould you like to continue?" << endl;
cout << "Please type 'Y' for Yes, and 'N' for No." << endl;
cin >> COM;
}
}
};
int main(){
IOutro IObject;
Arith ArithObject;
while (COM == 'Y' || COM == 'y' ){ // made changes here
IObject.welcome();
ArithObject.calc();
ArithObject.sum(A,B);
IObject.commandInput();
}
IObject.goodbye();
return 0;
}
Note that for this code, you don't need #include<string> and have also made the code insensitive to case ( that is 'Y' or 'y' and 'N' or 'n' )
This will get rid of that nasty error you were getting.
Well, hope that fixes the problems ( well, this solved it for me )

C++ Could not convert input string when using cin and variables

I'm trying to do a simple program where the user inputs a string with his/her name, then if the string is equal to a certain name, it executes different commands.
It's something like this:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string input = "";
cout << "What's your name?:\n>";
getline(cin, input);
if(input = "Micaela"){
cout << "You're the best" << input << endl << endl;
}
else
cout << "You kinda suck" << input << endl << endl;
return 0;
}
When compiling, I get the following error:
13 22 C:\Users\Francisco\Desktop\cpp\holanena.cpp [Error] could not convert 'input.std::basic_string<_CharT, _Traits, _Alloc>::operator=, std::allocator >(((const char*)"Micaela"))' from 'std::basic_string' to 'bool'
use == instead of =
== is for comparison
= is for assingment
The problem occurs in the line
if(input = "Micaela")
which assigns "Micaela" to input. Use comparison operator == instead of assignment operator = to get what you want:
if(input == "Micaela")
if(input = "Micaela") is an assignment. You want if(input == "Micaela") instead, which is a comparison.