Compiler error when subtracting std::strings - c++

I'm a beginner in c++ so I'm just messing around with some stuff while reading articles and books. But I spent 20 minutes re-reading this over and over again and I can't tell what's wrong with it.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
cout << "Hello there, this is your personal simple calculator.";
cin.get();
cout << "Type in what you want to do. (Addition, Subtraction, Multiplication, Division)"<< endl;
string c;
getline (cin, c);
if (c == "Addition")
{
string a_1;
string a_2;
cout << "You chose addition. Press enter" << endl ;
cin.get();
cout << "Type in the first value: ";
getline( cin, a_1);
cout << "Type in the second value: ";
getline (cin, a_2);
cout << a_1 << " + " << a_2 << " = " << a_1 + a_2 << endl;
}
else
{
cout << "You spelled it wrong.";
return 0;
}
if ( c == "Subtraction")
{
string s_1;
string s_2;
cout << "You chose subtraction. Press enter" << endl ;
cin.get();
cout << "Type in the first value: ";
getline (cin, s_1);
cout << "Type in the second value: ";
getline (cin, s_2);
cout << s_1 << " - " << s_2 << " = " << s_1 - s_2 << endl;
}
}
I get this as the only error
42 83 C:\Users\Jason\Desktop\Lesson - Header Files\LH1.cpp [Error] no match for 'operator-' in 'first_argument - second_argument'
I don't get it. The addition sign works and everything but the subtraction works.
So I messed around with something else
cout << first_argument << " - " << second_argument << " = " << first_argument - second_argument << endl;
But that subtraction part works fine. I don't get it. Help please

string can deal with text. When you add two strings, they are concatenated ("2"+"2"=="22", not "4"). String doesn't have operator-.
To deal with floating-point numbers, use double. To deal with integers, use int:
double d1, d2;
//some output
cin >> d1;
//some output
cin >> d2;
cout << d1 << " - " << d2 << " = " << (d1-d2) << '\n';

The addition part works because string + string results in stringstring. It appends the two strings and returns a new string.
But subtracting two strings doesn't mean anything.
What I believe you actually want to do is convert the strings into numbers and then subtract the numbers.
To do that, you need to use something like the following:
double val_1, val_2;
cin >> val_1;
cin >> val_2;
cout << "result is " << (val_1 - val_2) << endl;
I put the subtraction inside parenthesis because I believe the << aka "shift" operator is on the same level as multiplication, which means that without them it would try to evaluate ("result is " << val_1) - (val_2 << endl).
Since I am not sure on operator precedence I checked http://en.cppreference.com/w/cpp/language/operator_precedence and found that << is lower than subtraction, so my parenthesis weren't necessary.

#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main()
{
cout << "Hello there, this is your personal simple calculator.";
cin.get();
cout << "Type in what you want to do. (Addition, Subtraction, Multiplication, Division)" << endl;
string c;
getline(cin, c);
if (c == "Addition")
{
int a_1;
int a_2;
cout << "You chose addition. Press enter" << endl;
cin.get();
cout << "Type in the first value: ";
cin >> a_1;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Type in the second value: ";
cin >> a_2;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << a_1 << " + " << a_2 << " = " << a_1 + a_2 << endl;
}
else if (c == "Subtraction")
{
int s_1;
int s_2;
cout << "You chose subtraction. Press enter" << endl;
cin.get();
cout << "Type in the first value: ";
cin >> s_1;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Type in the second value: ";
cin >> s_2;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << s_1 << " - " << s_2 << " = " << s_1 - s_2 << endl;
}
else
{
cout << "You spelled it wrong.";
return 0;
}
}
Use if else statements because otherwise your code won't have a chance to check to see if the user is trying to Subtract. It is best to leave the else at the very end.
Also changed the strings to ints because strings cannot subtract as they are not numbers.
On a final note, I used the cin.clear() & cin.ignore() to flush the cin buffer.

Related

how do you do a integer validation in C++?

ok, I have been looking for days now but I cant find anything that will work.
I have a program and I want to make sure that the user enters a integer and not a double.
this program works fine but I need to validate the numOne and numTwo to make sure they are integers and not doubles, (5.5)
int main()
{ //This is where my variables are stored
int numOne, numTwo, answer, rightAnswer, ranNumOne, ranNumTwo;
//this will display to the user to enter a range of numbers to be used
cout << "Please enter a set of numbers to be the range for the problems." << endl;
cout << "Please enter the beginning number." << endl;
cin >> numOne;
cout << "please enter the ending number." << endl;
cin >> numTwo;
//this makes sure that the user entered a integer(if not the program will close)
if (!(cin >> numOne))
{
cout << "You did not enter a integer PLEASE RE-RUN THE PROGRAM AND TRY AGAIN!" << endl;
cin.clear();
cin.ignore(100, '\n');
exit(0);
}
cout << "please enter the ending number." << endl;
cin >> numTwo;
//this makes sure that the user entered a number(if not the program will close)
if (!(cin >> numTwo))
{
cout << "You did not enter a integer PLEASE RE-RUN THE PROGRAM AND TRY AGAIN!" << endl;
cin.clear();
cin.ignore(100, '\n');
exit(0);
}
//this is where the first number is generated
srand(time(0));
ranNumOne = rand() % (numOne - numTwo) + 1;
system("PAUSE");
//this is where the second number is generated
srand(time(0));
ranNumTwo = rand() % (numOne - numTwo) + 1;
//this is where the calculations are done
rightAnswer = ranNumOne + ranNumTwo;
//this displays the problem that was generated
cout << "What is: " << endl;
cout << setw(11) << ranNumOne << endl;
cout << setw(6) << "+" << setw(3) << ranNumTwo << endl;
cout << " -------\n";
cin >> answer;
//this checks to see if the answer is right or not and displays the result
if (answer == rightAnswer)
{
cout << "Your answer was correct! " << endl;
}
else
cout << "The correct answer is: " << rightAnswer << endl;
return 0;
}
Use std:n:ci.fail() to see if it failed.
int numOne;
cin >> numOne;
if(cin.fail())
cout << "Not a number...")
Maybe even a nice template function.
template<typename T>
T inline input(const std::string &errmsg = "") {
T var;
std::cin >> var;
while (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(256, '\n');
std::cout << errmsg;
std::cin >> var;
}
return var;
}
Or not:
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <string>
#include <ctime>
#define DIFF(n1, n2) (n1 > n2 ? n1 - n2 : n2 - n1)
using namespace std;
int input(const string &firstmsg = "", const string &errmsg = "") {
int var;
std::cout << firstmsg;
std::cin >> var;
while (cin.fail()) {
cin.clear();
cin.ignore(256, '\n');
cout << errmsg;
cin >> var;
}
return var;
}
int main(){
//This is where my variables are stored
int numOne, numTwo, answer, rightAnswer, ranNumOne, ranNumTwo;
//this will display to the user to enter a range of numbers to be used
cout << "Please enter a set of numbers to be the range for the problems." << endl << endl;
numOne = input("Please enter the beginning number: ", "Invalid. Enter again: ");
//this asks the user for the second number
numTwo = input("Please enter the ending number: ", "Invalid. Enter again: ");
//this is where the first number is generated
srand(time(0));
ranNumOne = rand() % (DIFF(numOne, numTwo)) + 1; // ensures it will always be positive
system("PAUSE");
//this is where the second number is generated
srand(time(0));
ranNumTwo = rand() % (DIFF(numOne, numTwo)) + 1;
//this is where the calculations are done
rightAnswer = ranNumOne + ranNumTwo;
//this displays the problem that was generated
cout << "What is: " << endl;
cout << setw(11) << ranNumOne << endl;
cout << setw(6) << "+" << setw(3) << ranNumTwo << endl;
cout << " -------\n";
cin >> answer;
//this checks to see if the answer is right or not and displays the result
if (answer == rightAnswer){
cout << "Your answer was correct! " << endl;
}
else
cout << "The correct answer is: " << rightAnswer << endl;
return 0;
}
why not, get the number into a double and then see if that double is an int. ie
double d;
cin>>d;
if (ceil(d) != d)
cout >> " not an integer";

Simple calculator issues (Not outputting answers)

just started reading a C++ book and one of the practice problems was to write a small calculator that takes as input one of the four arithmetic operations, the two arguments to those operations, and then prints out the results.
Sadly, the program works up until the user inputs the arithmetic option.
So if I chose to do multiplication, id write "Multiplication" and it was just stay there and not do anything after.
Image of the problem im having
#include <iostream>
#include <string>
using namespace std;
int main(){
// Simple calculator program
// Declaring three variables
float numberOne;
float numberTwo;
string operationOption;
// Asking the user which two numbers he/she will use
cout << "Enter the first number you would like to apply a arithmetic operation to: ";
cin >> numberOne;
cin.ignore();
cout << "Now enter the second number: ";
cin >> numberTwo;
cin.ignore();
// Using cin to input users selection
cout << "Enter the operation you want to perform." << endl;
cout << "The options you have are: " << endl;
cout << "Multiplication, Subraction, Division and Addition: " << endl;
cin >> operationOption;
cin.ignore();
cin.get();
// Where it all happens
if ( operationOption == "Multiplication" ) {
cout << "The first number multiplied by the second number is: " << numberOne * numberTwo << endl;
} else if ( operationOption == "Division" ) {
cout << "The first number divided by the second number is: " << numberOne / numberTwo << endl;
} else if ( operationOption == "Subtraction" ) {
cout << "The first number subtracted by the second number is: " << numberOne - numberTwo << endl;
} else if ( operationOption == "Addition ") {
cout << "The first number added to the second number is: " << numberOne + numberTwo << endl;
} else {
cout << "You entered an invalid option.";
};
}
Remove line :
cin.get();
will solve your problem

I am trying to use a do while loop to repeat a certain portion of my program and it refuses to execute properly

Okay so as the title said its refusing to execute the stuff right under the "do" function even though as far as i can tell all the parameters for a repeat have been fulfilled. So far what i get when i run the program is something along the lines of...
"Would you like to search another name?
Please enter Y for yes and n for no:"
looping over and over when i press y
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main()
{
vector <string> vName, vID, vClass;
string sName, sID, sClass, sSearch, cQuestion;
int iSize, iStudent;
// Display initial vector size
iSize = vName.size();
cout << "Student list starts with the size:" << iSize << endl;
// Get size of list from user
cout << "How many students would you like to add?" << endl;
cin >> iStudent;
cin.ignore();
// Get names, ids, and classes
for (int i = 0; i < iStudent; i++)
{
cout << "Student" << i + 1 << ":\n";
cout << "Please enter the student name: ";
getline(cin, sName);
vName.push_back(sName);
cout << "Enter ID number ";
getline(cin, sID);
vID.push_back(sID);
cout << "Enter class name ";
getline(cin, sClass);
vClass.push_back(sClass);
}
// Display header
cout << "The list of students has the size of: " << iStudent << endl;
cout << "The Student List" << endl;
cout << "\n";
cout << "Name:" << setw(30) << "ID:" << setw(38) << "Enrolled Class : " << endl;
cout << "--------------------------------------------------------------------------";
cout << "\n";
// for loop for displying list
for (int x = 0; x < vName.size() && vID.size() && vClass.size(); x++)
{
cout << vName[x] << "\t \t \t" << vID[x] << "\t \t \t" << vClass[x] << endl;
}
// Sorting function
cout << "\n";
cout << "The Student List after Sorting:" << endl;
cout << "\n";
sort(vName.begin(), vName.end());
for (int y = 0; y < vName.size(); y++)
{
cout << vName[y] << endl;
}
cout << "\n";
// Search function
do
{
cout << "Please Enter a name to be searched:" << endl;
getline(cin, sSearch);
if (binary_search(vName.begin(), vName.end(), sSearch))
{
cout << sSearch << " was found." << endl << endl;
}
else
{
cout << sSearch << " was not found." << endl << endl;
}
cout << "Would you like to search another name?" << endl << endl;
cout << "Please enter Y for Yes and N for No:" << endl << endl;
cin >> cQuestion;
} while (cQuestion == "Y" || cQuestion == "y");
cout << "Thank you for using this program!" << endl;
return 0;
}
Edit:
Posted whole program, please excuse any grammatical mistakes, I'm just trying to get the program down before i go in there and make it pretty.
The tail of your loop does this:
cout << "Please enter Y for Yes and N for No:" << endl << endl;
cin >> cQuestion;
which will consume your string if you entered one, but leave the trailing newline in the input stream. Thus when you return to the top of the loop after entering Y or y, and do this:
cout << "Please Enter a name to be searched:" << endl;
getline(cin, sSearch);
the getline will extract an empty line.
How to consume the unread newline from the input stream is up to you. You will likely just end up using .ignore() as you did prior in your program. Or use getline to consume cQuestion. You have options. Pick one that works.
And as a side note, I would strongly advise you check your stream operations for success before assuming they "just worked". That is a hard, but necessary, habit to break. Something like this:
do
{
cout << "Please Enter a name to be searched:" << endl;
if (!getline(cin, sSearch))
break;
if (binary_search(vName.begin(), vName.end(), sSearch))
{
cout << sSearch << " was found." << endl << endl;
}
else
{
cout << sSearch << " was not found." << endl << endl;
}
cout << "Would you like to search another name?" << endl << endl;
cout << "Please enter Y for Yes and N for No:" << endl << endl;
} while (getline(cin,cQuestion) && (cQuestion == "Y" || cQuestion == "y"));
If cQuestion is a char array then you need to use strcmp or stricmp to compare it with another string i.e. "Y" and "y" in this case. If cQuestion is a single char then you need to compare with 'Y' and 'y' (i.e. with a single quote)
Strings in C++ are not first class types therefore they do not have some of the string operation that exist for other basic types like ints and floats. You do have std::string as part of the standard C++ library which almost fulfills the void.
If you just change the type of cQuestion to std::string your code should work but if you want to stick with chars then you will need to change the quote style.

How can I avoid bad input from a user?

I am a very newbie programmer, so I don't really know much about writing code to protect the application.. Basically, I created a basicMath.h file and created a do while loop to make a very basic console calculator (only two floats are passed through the functions). I use a series of if and else if statements to determine what the users wants to do. (1.add, 2.subtract, 3.multiply, 4.divide) I used a else { cout << "invalid input" << endl;} to protect against any other values, but then I tried to actually write a letter, and the program entered a infinite loop. Is there anyway to protect against users who accidentally hit a character instead of a number?
`#include <iostream>
#include "basicMath.h"
using namespace std;
char tryAgain = 'y';
float numOne = 0, numTwo = 0;
int options = 0;
int main()
{
cout << "welcome to my calculator program." << endl;
cout << "This will be a basic calculator." << endl;
do{
cout << "What would you like to do?" << endl;
cout << "1. Addition." << endl;
cout << "2. Subtraction." << endl;
cout << "3. Multiplication" << endl;
cout << "4. Division." << endl;
cin >> options;
if (options == 1){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " + " << numTwo << " = " << add(numOne, numTwo) << endl;
}
else if (options == 2){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " - " << numTwo << " = " << subtract(numOne, numTwo) << endl;
}
else if (options == 3){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " * " << numTwo << " = " << multiply(numOne, numTwo) << endl;
}
else if (options == 4){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " / " << numTwo << " = " << divide(numOne, numTwo) << endl;
}
else {
cout << "Error, invalid option input." << endl;
}
cout << "Would you like to use this calculator again? (y/n)" << endl;
cin >> tryAgain;
}while (tryAgain == 'y');
cout << "Thank you for using my basic calculator!" << endl;
return 0;
}
`
One way would be to use exception handling, but as a newbie you're probably far from learning that.
Instead use the cin.fail() which returns 1 after a bad or unexpected input. Note that you need to clear the "bad" status using cin.clear().
A simple way would be to implement a function:
int GetNumber ()
{
int n;
cin >> n;
while (cin.fail())
{
cin.clear();
cin.ignore();
cout << "Not a valid number. Please reenter: ";
cin >> n;
}
return n;
}
Now in your main function wherever you are taking input, just call GetNumber and store the returned value in your variable. For example, instead of cin >> numOne;, do numOne = GetNumber();
When you input to cin, it is expecting a specific type, such as an integer. If it receives something that it does not expect, such as a letter, it sets a bad flag.
You can usually catch that by looking for fail, and if you find it, flush your input as well as the bad bit (using clear), and try again.
Read a whole line of text first, then convert the line of text to a number and handle any errors in the string-to-number conversion.
Reading a whole line of text from std::cin is done with the std::getline function (not to be confused with the stream's member function):
std::string line;
std::getline(std::cin, line);
if (!std::cin) {
// some catastrophic failure
}
String-to-number conversion is done with std::istringstream (pre-C++11) or with std::stoi (C++11). Here is the pre-C++11 version:
std::istringstream is(line);
int number = 0;
is >> number;
if (!is) {
// line is not a number, e.g. "abc" or "abc123", or the number is too big
// to fit in an int, e.g. "11111111111111111111111111111111111"
} else if (!is.eof()) {
// line is a number, but ends with a non-number, e.g. "123abc",
// whether that's an error depends on your requirements
} else {
// number is OK
}
And here the C++11 version:
try {
std::cout << std::stoi(line) << "\n";
} catch (std::exception const &exc) {
// line is not a number, e.g. "abc" or "abc123", or the number is too big
// to fit in an int, e.g. "11111111111111111111111111111111111"
std::cout << exc.what() << "\n";
}

Check for non-numeric inputs in a C++ program

How do you check for non-numeric input using C++? I am using cin to read in a float value, and I want to check if non-numerical input is entered via stdin. I have tried to use scanf using the %d designator, but my output was corrupted. When using cin, I get the correct format, but when I enter, a string such as "dsffsw", I get an infinite loop.
The commented code was my attempt to capture the float, and type cast it as string, and check if it is a valid float, but the check always comes up false.
I have tried using other methods I have found on the message boards, but they want to use scanf in C and not cin in C++. How do you do this in C++? Or in C if it is not feasible.
while (!flag) {
cout << "Enter amount:" << endl;
cin >> amount;
cout << "BEGIN The amount you entered is: " << strtod(&end,&pend) << endl;
//if (!strtod(((const char *)&amount), NULL)) {
// cout << "This is not a float!" << endl;
// cout << "i = " << strtod(((const char *)&amount), NULL) << endl;
// //amount = 0.0;
//}
change = (int) ceil(amount * 100);
cout << "change = " << change << endl;
cout << "100s= " << change/100 << endl;
change %= 100;
cout << "25s= " << change/25 << endl;
change %= 25;
cout << "10s= " << change/10 << endl;
change %= 10;
cout << "5s= " << change/5 << endl;
change %= 5;
cout << "1s= " << change << endl;
cout << "END The amount you entered is: " << amount << endl;
}
return 0;
}
int amount;
cout << "Enter amount:" << endl;
while(!(cin >> amount)) {
string garbage;
cin.clear();
getline(cin,garbage);
cout << "Invalid amount. "
<< "Enter Numeric value for amount:" << endl;
}
I think you task relates to the so called defensive programming, one of it`s ideas is to prevent situations like one you described (function expects one type and user enters another).
I offer you to judge whether input is correct using method that returns stream state , which is good(),
so I think it will look something like this:
int amount = 0;
while (cin.good()) {
cout << "Enter amount:" << endl;
cin >> amount;