I am writing an IP calculator program to convert an IP adress into the broadcast adress, network adress etc.
I need to convert the adress into 8-digit biniary first, I already used itoa for it decimal to biniary conversion, but I still need to make it always 8 digit.
I want to use a switch to do it. First the program counts the number of digits in the binary form, and then, using switch (I put it into a comment, I need to figure out this proble first) and if it adds enough zeros in front of the number (actually a string at this point) so it would always be 8 characters long.
I want to use string e1('00',e); instruction to add two zeros to the string, but it doesn't work. e is the original string, e1 is the new 8 character string. It doesn't want to compile, stops at this line (string e1('00',e);) and gives:
error: no matching function for call to 'std::__cxx11::basic_string<char>::
basic_string(int, std::__cxx11::string)'|
My code:
#include <iostream>
#include <string>
#include <bits/stdc++.h>
using namespace std;
/**
* C++ version 0.4 std::string style "itoa":
* Contributions from Stuart Lowe, Ray-Yuan Sheu,
* Rodrigo de Salvo Braz, Luc Gallant, John Maloney
* and Brian Hunt
*/
std::string itoa(int value, int base)
{
std::string buf;
// check that the base if valid
if (base < 2 || base > 16)
return buf;
enum
{
kMaxDigits = 35
};
buf.reserve(kMaxDigits); // Pre-allocate enough space.
int quotient = value;
// Translating number to string with base:
do
{
buf += "0123456789abcdef"[std::abs(quotient % base)];
quotient /= base;
} while (quotient);
// Append the negative sign
if (value < 0)
buf += '-';
std::reverse(buf.begin(), buf.end());
return buf;
}
int main()
{
cout << "Dzien dobry." << endl
<< "Jest OK!\n";
int a, b, c, d, i, j, k, l, m, n, o, p, r, s, t, u, w, v, x, y, z;
cout << "Wprowadz pierwszy oktet: ";
cin >> a;
cout << "Wprowadz drugi oktet: ";
cin >> b;
cout << "Wprowadz trzeci oktet: ";
cin >> c;
cout << "Wprowadz czwarty oktet: ";
cin >> d;
cout << "Wyswietlam adres IP w postaci dziesietnej: " << a << "." << b << "." << c << "." << d << "\n";
char res[1000];
itoa(a, res, 2);
string e(res);
itoa(b, res, 2);
string f(res);
itoa(c, res, 2);
string g(res);
itoa(d, res, 2);
string h(res);
//
x = e.size();
cout << x << "\n";
/*
if (x<8)
{
switch(x)
{
case 1: string e(1);
break;
case 2: string e(3);
break;
case 3: string e(2);
break;
case 4: string e(0);
break;
case 5: string e(4);
break;
case 6: string e(7);
break;
case 7: string e(0);
break;
default: cout << "error";
}
}
*/
string e1('00', e);
cout << e1 << "\n";
cout << "Wyswietlam adres IP w postaci dwojkowej: " << e1 << "." << f << "." << g << "." << h;
return 0;
}
Single quotation marks are for single characters, double quotation marks are for strings, i.e. more than one character, so you need "00".
There is no std::string constructor for the parameters you provide, among other methods, you can use:
string e1;
e1.append("00").append(e);
Or
string e1 = "00";
e1 += e;
Aditional notes:
Avoid using #include <bits/stdc++.h>
Avoid using using namespace std;
Just use + or +=:
std::string foo = "Hello";
std::string bar = foo + " world";
std::cout << bar; // Prints Hello world
You can also modify a string in-place with +=:
std::string foo = "Hello";
foo += " world"; // foo is "Hello world" now
Note that this invalidates any existing iterators you had that pointed to characters inside foo. You can get the new begin and end iterators by just calling begin and end again.
Related
I am so close to solving this roman numeral to integer problem. However, in my if statement for when character equals M, I am getting an error thrown when declaring my previous variable when the input is MCMXCIV for example. Because there is nothing before M, it is throwing an out-of-bounds error. How can I fix this?
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
using namespace std;
//Character to search and add to the integer
char character;
//The integer value that is needed to add up and output the corresponding value
int integer = 0;
//One of the test runs and what will be needed for every special case
int main()
{
//Roman numeral given
string input;
//Prompt for user to enter the roman numeral integer
cout << "Enter the roman numeral you want to convert into a number: " << endl;
cin >> input;
cout << input << " is what you are wanting to convert." << endl;
//Read through the string that is being inputted then assign values to the overall integer
for (int i = 0; i < input.length(); i++)
{
character = input.at(i);
cout << "This is the character that is being read right now: " << character << endl;
//Arithmitic for when the character is found and the corresponding value needs to be added
if(character == 'I')
{
integer+=1;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'V')
{
char previous = input.at(i-1);
integer+=5;
if(character == 'V' && previous == 'I')
{
integer = integer - 2;
}
cout << "Integer value now: " << integer << endl;
}
else if(character == 'X')
{
integer+=10;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'L')
{
integer+=50;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'C')
{
integer+=100;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'D')
{
integer+=500;
cout << "Integer value now: " << integer << endl;
}
else if(character == 'M')
{
char previous = input.at(i-1);
integer+=1000;
if(character == 'M' && previous == 'C')
{
integer -= 200;
}
cout << "Integer value now: " << integer << endl;
}
}
cout << "The integer value is: " << integer << endl;
}
First of all: Good that you used the at() function. So you could detect the "out of bounds" problem.
in char previous = input.at(i - 1);, variable "i" could be 0 and you then try to access array element "-1", which is of course out of bounds for your use case.
So, you need an additional check, if "i" greater then 0, before subtracting.
But in general, your approach is too complicated. You can make your life easier, by analyzing or reading, how roman numerals are defined. Look for example here. And please read especially about the "subtractive notation".
You already noticed that but, unfortunately, your implementation is not always following that rule. You made the check only for "M" and "V". But basically, you need to do that for all literals (except "I").
You can boil down this to the rule:
If a literal before a following literal is less, then use the subtrative form. Or, even better, you can read from right to left and finally say:
"If the current literal is less than the follwoing, then use the subtractive form."
And what is the subtractive form? We can simply add the negative number. Example, using number 94 which is "XCIV". We start summing up from the right:
Start. Begin from right. Initialize sum with rightmost value: Looking at 'V': sum = 5
Next: Read 'I'. Check, if this is less than the following literal 'V'. Yes, it is. So, use subtractive form. Add the negative. Now sum = sum + (-1), sum = 4
Now: Read 'C'. Check, if this is less than the following literal 'I'. No, it is not. So, simply add the positive value. Now sum = sum + 100, sum = 104
Next: Read 'X'. Check, if this is less than the following literal 'C' . Yes, it is. So, use subtractive form. Add the negative. Now sum = sum + (-10), sum = 94
So, this is now a very simply algorithm. We will convert a roman literal (one letter) to a integer and then build a sum with positive or negative values.
One of many many potential implementations could look like this:
#include <iostream>
#include <string>
int convert(char romanLiteral) {
switch (romanLiteral) {
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default:
return 0;
}
}
int romanLiteralStringToInteger(const std::string& romanLiteralString) {
// Sanity check:
if (romanLiteralString.empty()) return 0;
// Get length of input string
int lengthOfRomanLiteralString = static_cast<int>(romanLiteralString.length());
// Initialize sum with rightmost value
int sum = convert(romanLiteralString[lengthOfRomanLiteralString-1]);
// Now iterate over the string form right to left
for (int i = lengthOfRomanLiteralString - 2; i >= 0; --i) {
// Check if this literal is less than the following
if (convert(romanLiteralString[i]) < convert(romanLiteralString[i+1]))
sum -= convert(romanLiteralString[i]);
else
sum += convert(romanLiteralString[i]);
}
return sum;
}
int main() {
std::string romanNumber = "XCIV";
std::cout << romanNumber << " --> " << romanLiteralStringToInteger(romanNumber) << '\n';
}
In C++ you would probably use associative containers like std::map or std::unordered_map for converting one literal to a number. And maybe a ternary operator, instead of an if.
Then the problem could be implemented like the following:
#include <iostream>
#include <string>
#include <unordered_map>
int romanLiteralStringToInteger(const std::string& romanLiteralString) {
if (romanLiteralString.empty()) return 0;
std::unordered_map<char, int> T = { { 'I' , 1 }, { 'V' , 5 }, { 'X' , 10 }, { 'L' , 50 }, { 'C' , 100 }, { 'D' , 500 }, { 'M' , 1000 } };
int sum = T[romanLiteralString.back()];
for (int i = romanLiteralString.length() - 2; i >= 0; --i)
sum += (T[romanLiteralString[i]] < T[romanLiteralString[i + 1]] ? -T[romanLiteralString[i]] : T[romanLiteralString[i]]);
return sum;
}
int main() {
std::string romanNumber = "XCIV";
std::cout << romanNumber << " --> " << romanLiteralStringToInteger(romanNumber) << '\n';
}
And the hardcore solution with a stateful lambda.
#include <iostream>
#include <string>
#include <unordered_map>
#include <numeric>
#include <iterator>
std::unordered_map<char, int> ARTI{{'I',1 },{'V',5 },{'X',10 },{'L',50 },{'C',100},{'D',500 },{'M',1000 }};
int main() {
std::string romanNumber = "XCIV";
std::cout << std::accumulate(std::next(romanNumber.rbegin()), romanNumber.rend(), ARTI[romanNumber.back()], [&, next = ARTI[romanNumber.back()]](const int s, const char c) mutable {
int sum = s + (ARTI[c] < next ? -ARTI[c] : ARTI[c]); next = ARTI[c]; return sum; });
}
I input a number in char type variable. like 12 or 22. but, console show me a 1 or 2.
How i get a whole number 12 ,22 in console?
#include <iostream>
int main()
{
using namespace std;
char a = 0;
cin >> a;
cout << a << endl;
return 0;
}
Here is console result.
12
1
C:\Users\kdwyh\source\repos\MyFirstProject\Debug\MyFirstProject.exe(프로세스 18464개)이(가) 종료되었습니다(코드: 0개).
이 창을 닫으려면 아무 키나 누르세요...
The reason I don't use int, string and something is because I want to get both number and Character in one variable.
So I want to see the results of combined numbers and character at the same time.
in that process i can't get a whole number.
#include <iostream>
using namespace std;
int index = 0;
constexpr int pagenum = 10;
void chapterlist(void);
void nextlist(void);
void beforelist(void);
void movechapter(char a);
int main(void)
{
char userin = 0;
bool toggle = 0;
cout << "결과를 볼 챕터를 고르시오." << endl;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cin >> userin;
if (userin == 'n')
{
backflash:
while(toggle == 0)
{
nextlist();
cin >> userin;
if (userin == 'b')
{
toggle = 1;
goto backflash;
}
else if (userin == 'n')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
while(toggle == 1)
{
beforelist();
cin >> userin;
if (userin == 'n')
{
toggle = 0;
goto backflash;
}
else if (userin == 'b')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
}
else
{
system("cls");
movechapter(userin);
}
return 0;
}
void chapterlist(void)
{
int x = 0;
for (x = index + 1; x <= index + 10; x++)
cout << "Chapter." << x << endl;
}
void nextlist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index + pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void beforelist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index - pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void movechapter(char a)
{
cout << "선택한 Chapter." << a << "의 결과입니다." << endl;
}
In movechapter(), console show me a is 1 or 2, not 12, 22.
First, you have to understand what achar type is.
Character types: They can represent a single character, such as 'A' or '$'. The most basic type is char, which is a one-byte character. Other types are also provided for wider characters.
To simplify that, char can only hold one character.
Where as with your code, "12" is actually 2 separate characters, '1' and '2', and that's the reason it would not work.
Instead of declaring a as a char type, you could declare it as an int type, which is a type designed to hold numbers. So you would have:
int a = 0;
However, do note that int often has a maximum value of 2^31.
Or you could use std::string to store character strings. However, do note that if you wish to do any calculations to your string type, you would need to convert them to a number type first:
int myInt = std::stoi(myString);
Edit:
So I have re-checked your code after your update, there is nothing wrong with using std::string in your case. You can still check if user have input n or b by:
if (userin == "n")
Note that you would use double quotation mark, or "letter", around the content that you want to check.
On the other hand, you could use:
if(std::all_of(userin .begin(), userin.end(), ::isdigit))
To check if user have input a number.
Although char is just a number, it's presumed to mean "single character" here for input. Fix this by asking for something else:
int a = 0;
You can always cast that to char as necessary, testing, of course, for overflow.
You should be reading characters into a string, and then converting that string into an int. It would also probably make more sense to use something like getline() to read input, rather than cin >> a.
#include <string>
#include <iostream>
#include <stdexcept>
#include <stdio.h>
int main() {
std::string input_string;
/* note that there is no function that will convert an int string
to a char, only to an int. You can cast this to a char if needed,
or bounds check like I do */
int value;
while(1) {
getline(std::cin, input_string);
/* std::stoi throws std::invalid_argument when given a string
that doesn't start with a number */
try {
value = std::stoi(input_string);
} catch (std::invalid_argument) {
printf("Invalid number!\n");
continue;
}
/* You wanted a char, the max value of a `char` is 255. If
you are happy for any value, this check can be removed */
if (value > 255) {
printf("Too big, input a number between 0-255\n");
continue;
}
break;
}
printf("Number is %hhu\n", value);
}
Good afternoon everyone, I am new to recursion and am trying to create a program to take user input to build a math function. It works when doing simple things such as 3 + 4, but when trying something like (3 + 4) + 6 the main prints an empty string. The purpose of the program is to place nested numbers inside parenthesis to make them clear to read. I have tried following the code, but the recursion seems to be what i don't understand. Thanks for your time and help.
Code
#include <iostream>
#include <string>
using namespace std;
string buildEq(bool nested, string tab);
int main()
{
cout << "Welcome to the equation builder!" << endl << endl;
cout << "Each step can only have one operation between two numbers." << endl;
cout << "So the equation (3 + 4) + 6 would have one 'nested' operation." << endl << endl;
string equation = buildEq(false, "");
cout << endl << "The equation you have built is... " << equation << endl;
cout << endl << "Thanks for coming!" << endl;
return 0;
}
string buildEq(bool nested, string tab)
{
string equation;
string nesting;
cout << tab << "For this step, is there nesting? (y/n): ";
cin >> nesting;
if(nesting == "y")
{
nested = true;
tab += "\t";
buildEq(true, tab);
}
else
{
int number = 0;
int operation_count = 1;
while(number < 2)
{
if(nested == true)
{
equation += "(";
}
string num= "";
cout << tab << "What number would you like to enter: ";
cin >> num;
equation += num+= " ";
number++;
while(operation_count == 1)
{
string operation;
cout << tab << "What operation would you like to perform? (+, -, /, *): ";
cin >> operation;
equation += operation += " ";
operation_count++;
}
if(nested == true && number == 2)
{
equation += ")";
}
}
}
return equation;
}
Correct output
Welcome to the equation builder!
Each step can only have one operation between two numbers.
So the equation (3 + 4) + 6 would have one 'nested' operation.
For this step, is there nesting? (y/n): n
What number would you like to enter: 3
What operation would you like to perform? (+, -, /, *): +
What number would you like to enter: 4
The equation you have built is... 3 + 4
Thanks for coming!
Press <RETURN> to close this window...
Function results empty
Welcome to the equation builder!
Each step can only have one operation between two numbers.
So the equation (3 + 4) + 6 would have one 'nested' operation.
For this step, is there nesting? (y/n): y
For this step, is there nesting? (y/n): n
What number would you like to enter: 3
What operation would you like to perform? (+, -, /, *): +
What number would you like to enter: 4
The equation you have built is...
Thanks for coming!
Press <RETURN> to close this window...
(Probably an overkill, but I don't think that the question itself is an easy example for understanding recursions)
In order to understand the recursion part, we need to look at the general problem, and understand how we progress from one invocation to another (the recursive step), and what is our stopping point (the base case) . Your goal here is to create a valid equation, in order to do so, your input should follow certain guidelines. Specifically, in order to verify such a problem, you need to verify that each input is following a syntax which is called Context Free Grammar, denoted by the following rules (N stands for number or nested, O for operation, D for digit and $ for nothing):
N -> ( N ) O | D O
D -> 0-9
O -> + N | - N | * N | / N | $
There are two recursions here. In each stage we need to get a valid equation, and those rules make sure it stays like that.
The following code is creating a proper equation from the user.
Notice a few important notes -
I'm using std::stringstream, which is more efficient at creating strings and appending to the existing "string".
You should not over-use std::endl, since in addition to adding a line break, it also flushes to the stdout, which is expensive.
Using "Using namespace std;" isn't a good habit!
Look at how I pass the same stringstream, and each stage adds to this, in order to create the general string. If your code doesn't add to the "carried" value, it means that you are doing nothing in this recursive step.
The code:
#include <sstream>
#include <iostream>
#include <string>
#include <cctype>
#include <assert.h>
void get_num_or_nested(std::stringstream& eq);
void get_operation_or_stop(std::stringstream& eq);
bool is_number(const std::string& s)
{
int digit_count = 0;
for (const char& character : s)
{
if (std::isdigit(character))
{
++digit_count;
}
}
return !s.empty() && s.size() == digit_count;
}
bool is_operation(char c)
{
return (c == '+' || c == '-' || c == '*' || c == '/');
}
std::string get_input_from_user()
{
std::string input;
std::cin >> input;
return input;
}
void get_operation_or_stop(std::stringstream& eq)
{
std::cout << "Insert one of the following:\n";
std::cout << "An operation - [ + | - | * | / ]\n";
std::cout << "s for Stop" << std::endl;
std::string input = get_input_from_user();
if (input.size() == 1)
{
if (is_operation(input[0]))
{
eq << input;
get_num_or_nested(eq);
}
else if (input != "s")
{
assert(false);
}
// stops!
}
else
{
assert(false);
}
}
void get_num_or_nested(std::stringstream& eq)
{
std::cout << "Insert one of the following:\n";
std::cout << "A number\n";
std::cout << "n for Nested" << std::endl;
std::string input = get_input_from_user();
if (input == "n")
{
eq << "(";
get_num_or_nested(eq);
eq << ")";
get_operation_or_stop(eq);
}
else if (is_number(input))
{
eq << input;
get_operation_or_stop(eq);
}
else
{
assert(false);
}
}
int main()
{
std::cout << "Welcome to the equation builder!\n" << std::endl;
std::stringstream eq;
get_num_or_nested(eq);
std::cout << "The equation you have built is... " << eq.str() << std::endl;
std::cout << "Thanks for coming!" << std::endl;
}
The only thing that is wrong is when the user says yes to nesting. Instead of calling the function and discarding what it returned, you need to return what the function returned.
if(nesting == "y")
{
nested = true;
tab += "\t";
return buildEq(true, tab);
}
I was typing this and it asks the user to input two integers which will then become variables. From there it will carry out simple operations.
How do I get the computer to check if what is entered is an integer or not? And if not, ask the user to type an integer in. For example: if someone inputs "a" instead of 2, then it will tell them to reenter a number.
Thanks
#include <iostream>
using namespace std;
int main ()
{
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}
You can check like this:
int x;
cin >> x;
if (cin.fail()) {
//Not an int.
}
Furthermore, you can continue to get input until you get an int via:
#include <iostream>
int main() {
int x;
std::cin >> x;
while(std::cin.fail()) {
std::cout << "Error" << std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin >> x;
}
std::cout << x << std::endl;
return 0;
}
EDIT: To address the comment below regarding input like 10abc, one could modify the loop to accept a string as an input. Then check the string for any character not a number and handle that situation accordingly. One needs not clear/ignore the input stream in that situation. Verifying the string is just numbers, convert the string back to an integer. I mean, this was just off the cuff. There might be a better way. This won't work if you're accepting floats/doubles (would have to add '.' in the search string).
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
Heh, this is an old question that could use a better answer.
User input should be obtained as a string and then attempt-converted to the data type you desire. Conveniently, this also allows you to answer questions like “what type of data is my input?”
Here is a function I use a lot. Other options exist, such as in Boost, but the basic premise is the same: attempt to perform the string→type conversion and observe the success or failure:
template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof()) // attempt the conversion
? value // success
: std::optional<T> { }; // failure
}
Using the optional type is just one way. You could also throw an exception or return a default value on failure. Whatever works for your situation.
Here is an example of using it:
int n;
std::cout << "n? ";
{
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x) return complain();
n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
limitations and type identification
In order for this to work, of course, there must exist a method to unambiguously extract your data type from a stream. This is the natural order of things in C++ — that is, business as usual. So no surprises here.
The next caveat is that some types subsume others. For example, if you are trying to distinguish between int and double, check for int first, since anything that converts to an int is also a double.
There is a function in c called isdigit(). That will suit you just fine. Example:
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) )
{
printf("var1 = |%c| is a digit\n", var1 );
}
else
{
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
printf("var2 = |%c| is a digit\n", var2 );
}
else
{
printf("var2 = |%c| is not a digit\n", var2 );
}
From here
If istream fails to insert, it will set the fail bit.
int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
std::cout << "I failed, try again ..." << std::endl
std::cin.clear(); // reset the failed state
}
You can set this up in a do-while loop to get the correct type (int in this case) propertly inserted.
For more information: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly
You can use the variables name itself to check if a value is an integer.
for example:
#include <iostream>
using namespace std;
int main (){
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
if(firstvariable && secondvariable){
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}else{
cout << "\n[ERROR\tINVALID INPUT]\n";
return 1;
}
return 0;
}
I prefer to use <limits> to check for an int until it is passed.
#include <iostream>
#include <limits> //std::numeric_limits
using std::cout, std::endl, std::cin;
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Reenter the number: ";
};
cout << "output= " << num << endl;
return 0;
}
Under C++11 and later, I have the found the std::stoi function very useful for this task. stoi throws an invalid_argument exception if conversion cannot be performed. This can be caught and handled as shown in the demo function 'getIntegerValue' below.
The stoi function has a second parameter 'idx' that indicates the position of the first character in the string after the number. We can use the value in idx to check against the string length and ascertain if there are any characters in the input other than the number. This helps eliminate input like 10abc or a decimal value.
The only case where this approach fails is when there is trailing white space after the number in the input, that is, the user enters a lot of spaces after inputting the number. To handle such a case, you could rtrim the input string as described in this post.
#include <iostream>
#include <string>
bool getIntegerValue(int &value);
int main(){
int value{};
bool valid{};
while(!valid){
std::cout << "Enter integer value: ";
valid = getIntegerValue(value);
if (!valid)
std::cout << "Invalid integer value! Please try again.\n" << std::endl;
}
std::cout << "You entered: " << value << std::endl;
return 0;
}
// Returns true if integer is read from standard input
bool getIntegerValue(int &value){
bool isInputValid{};
int valueFromString{};
size_t index{};
std::string userInput;
std::getline(std::cin, userInput);
try {
//stoi throws an invalid_argument exception if userInput cannot be
//converted to an integer.
valueFromString = std::stoi(userInput, &index);
//index being different than length of string implies additional
//characters in input that could not be converted to an integer.
//This is to handle inputs like 10str or decimal values like 10.12
if(index == userInput.length()) isInputValid = true;
}
catch (const std::invalid_argument &arg) {
; //you could show an invalid argument message here.
}
if (isInputValid) value = valueFromString;
return isInputValid;
}
You could use :
int a = 12;
if (a>0 || a<0){
cout << "Your text"<<endl;
}
I'm pretty sure it works.
I am trying to write a function in C++ to evaluate a postfix notation equation. My general strategy is to scan a string (in the proper format, e.g. "10 20 + 30 -").
I am doing this by incrementing an index variable i. At each increment, I check to see if the character is a digit, operator, or neither. If it's a digit, I use the getNextNum() function to get all following digits, convert that to a float, then push it to a stack. I also increment i by the length of the number captured.
If the character is an operator, I get the top two elements of the stack, do the operation, then push the result back to the stack.
The trouble is, my while loop only seems to go through once. The function only returns the first number in the string. I can't figure out what's wrong, I would appreciate any help! I inserted cout statements in the while loop, and i is only incrementing to the index after the first number.
EDIT: Ok, I added the getNextNum() function. Also, I updated the evalPostfix() with a cout of strLength, as well as i after each iteration of the while loop. When running the given code, I get this:
Running…
Please enter an expression in postfix notation: 555 666+
3
555
3
Your expression evaluates to: 555
It seems like strLength is being set to less than it should. Why could this be?
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <stack>
using namespace std;
string getNextNum(string equation, int i);
float evalPostfix(string postfix);
float doOperation(float x, float y, char op);
float doOperation(float x, float y, char op)
{
switch (op) {
case '+':
return x + y;
case '-':
return x - y;
case '*':
return x * y;
case '/':
return x / y;
default:
return 0.0;
}
}
string getNextNum(string equation, int i)
{
string num = "";
const string DELIM = "+-*/%^ ";
while (i<equation.length()) {
// Iterate through equation until you hit a delimiter.
if (DELIM.find(equation[i]) != -1) {
break;
}
num += equation[i];
i++;
}
return num;
}
float evalPostfix(string postfix)
{
const string OPS = "+-*/%^";
const string NUMS = "0123456789";
int strLength = postfix.length();
stack<float> numStack;
int i = 0;
cout << strLength << endl;
while (i<strLength) {
if (NUMS.find(postfix[i]) != -1) {
// If a character is a digit, then you should get the
// value and push it to the stack (could be multiple characters long).
string sNextNum = getNextNum(postfix, i);
float fNextNum = atof(sNextNum.c_str());
numStack.push(fNextNum);
cout << sNextNum << endl;
i += (sNextNum.length() - 1);
}
else if (OPS.find(postfix[i] != -1)) {
// Otherwise, pop the top two elements of the stack, perform the
// operation, then push the result back to the stack.
char op = postfix[i];
float x = numStack.top();
numStack.pop();
float y = numStack.top();
numStack.pop();
float z = doOperation(x, y, op);
numStack.push(z);
}
i++;
cout << i << endl;
};
// Once the entire string has been scanned through, there should be a float
// left in the stack, simply return that.
return numStack.top();
}
int main ()
{
cout << "Please enter an expression in postfix notation: ";
string postfix;
cin >> postfix;
float eval = evalPostfix(postfix);
cout << "Your expression evaluates to: " << eval;
return 0;
}
You have a few issues one of the major one being a typo, you have a misplaced ) this:
else if (OPS.find( postfix[i] != -1 ) ) {
^ ^
should be:
else if (OPS.find( postfix[i] ) != std::string::npos) {
^ ^
so you are comparing the char at position i to -1 and then doing a find on the boolean result. Next you should be using -1 to compare the results of find but std::string::npos
As Jonathan pointed out:
cin >> postfix ;
only read up to the first black or newline. Using getline will fix that problem:
if (getline(cin, postfix))
One primary problem was that the input cin >> postfix; statement only reads the first word. Echo inputs to ensure that the program is seeing what you think it is seeing.
Shafik Yaghmour points out another problem.
Points to learn:
echo inputs to make sure the program is seeing what you think it is seeing;
trace key variables with suitable printing messages;
post SSCCE (Short, Self-Contained, Correct Example) — code that can be compiled;
post example input and the output you're getting from it.
This code works on input 555 666+:
#include <iostream>
#include <string>
#include <stack>
using namespace std;
static float doOperation(float x, float y, char op)
{
cout << "doOp: x = " << x << ", y = " << y << ", op = " << op << endl;
if (op == '+')
x += y;
return x;
}
string getNextNum(string equation, int i)
{
string num = "";
const string DELIM = "+-*/%^ ";
while (i<equation.length()) {
// Iterate through equation until you hit a delimiter.
if (DELIM.find(equation[i]) != -1) {
break;
}
num += equation[i];
i++;
}
return num;
}
float evalPostfix(string postfix)
{
const string OPS = "+-*/%^";
const string NUMS = "0123456789";
int strLength = postfix.length();
stack<float> numStack;
int i = 0;
while (i<strLength) {
cout << "Top - i: " << i << ", strLength: " << strLength << endl;
if (NUMS.find(postfix[i]) != -1) {
// If a character is a digit, then you should get the
// value and push it to the stack (could be multiple characters long).
string sNextNum = getNextNum(postfix, i);
float fNextNum = atof(sNextNum.c_str());
numStack.push(fNextNum);
cout << sNextNum << endl;
i += (sNextNum.length() - 1);
}
else if (OPS.find(postfix[i])!= -1) {
// Otherwise, pop the top two elements of the stack, perform the
// operation, then push the result back to the stack.
char op = postfix[i];
float x = numStack.top();
numStack.pop();
float y = numStack.top();
numStack.pop();
float z = doOperation(x, y, op);
numStack.push(z);
}
i++;
cout << "End - i: " << i << ", strLength: " << strLength << endl;
}
cout << "After - i: " << i << ", strLength: " << strLength << endl;
// Once the entire string has been scanned through, there should be a float
// left in the stack, simply return that.
return numStack.top();
}
int main ()
{
cout << "Please enter an expression in postfix notation: ";
string postfix;
//cin >> postfix;
if (getline(cin, postfix))
{
cout << "Evaluating: " << postfix << endl;
float eval = evalPostfix(postfix);
cout << "Your expression evaluates to: " << eval << endl;
}
return 0;
}
Sample trace:
Please enter an expression in postfix notation: 555 666+
Evaluating: 555 666+
Top - i: 0, strLength: 8
555
End - i: 3, strLength: 8
Top - i: 3, strLength: 8
End - i: 4, strLength: 8
Top - i: 4, strLength: 8
666
End - i: 7, strLength: 8
Top - i: 7, strLength: 8
doOp: x = 666, y = 555, op = +
End - i: 8, strLength: 8
After - i: 8, strLength: 8
Your expression evaluates to: 1221
Clearly, you can lose much of the diagnostic output once the specific problem you are solving is resolved, but being prepared to add it along the lines shown can dramatically speed up the process of solving it.