I am writing a program that converts a parathensized expression into a mathematical one, and evaluates it. I've got the calculation bit written already.
I am using a stack for the operands, and a queue for the numbers. Adding operands to the stack isn't an issue, but I need to identify whether the input character is an integer, and if so, add it to the queue. Here's some code:
cout << "Enter the numbers and operands for the expression";
string aString;
do
{
cin >> aString
if (aString = int) // function to convert to read if int, convert to int
{
c_str(...);
atoi(...);
istack.push(int);
}
}
That's where I'm stuck now. I know I'm going to have to use c_str and atoi to convert it to an int. Am I taking the wrong approach?
Use the .fail() method of the stream.
If you need the string too, you can read to a string first, then attempt to convert the string to an integer using a stringstream object and check .fail() on the stringstream to see if the conversion could be done.
cin >> aString;
std::stringstream ss;
ss << aString;
int n;
ss >> n;
if (!ss.fail()) {
// int;
} else {
// not int;
}
I'll probably get flamed for this by the C++ purists.
However, sometimes the C++ library is just more work than the C library. I offer this
solution to C developers out there. And C++ developers who don't mind using some of the
features of the C library.
The whole check and conversion can be done in 1 line of C using the sscanf function.
int intval;
cin >> aString
if (sscanf(aString.c_str(), "%d", &intval)){
istack.push(intval);
}
sscanf returns the number of input arguments matched and assigned. So in this case, it's looking for one standard signed int value. If sscanf returns 1 then it succeeded in assigning the value. If it returns 0 then we don't have an int.
If you expect an integer, I would use boost::lexical_cast.
std::string some_string = "345";
int val = boost::lexical_cast<int>(some_string);
If it fails to cast to an integer, it will throw. The performance is pretty reasonable, and it keeps your code very clean.
I am unaware of any non-throwing version. You could use something like this, though I usually try to avoid letting exceptions control program flow.
bool cast_nothrow(const std::string &str, int &val) {
try {
val = boost::lexical_cast<int>(str);
return true;
} catch (boost::bad_lexical_cast &) {
return false;
}
}
Edit:
I would not recommend your integer validation checking for structure like you described. Good functions do one thing and one thing well.
Usually you'd want a more formal grammar parser to handle such things. My honest advice is to embed a scripting language or library in your project. It is non-trivial, so let someone else do the hard work.
If I actually tried to implement what you propose, I would probably do a stack based solution keeping the parenthesis levels at their own stack frame. The simplest thing would just be to hard code the simple operators (parenthesis, add, sub, etc) and assume that the rest of everything is a number.
Eventually you'd want everything broken down into some expression type. It might look something like this:
struct Expression {
virtual ~Expression() {}
virtual float value() const = 0;
};
struct Number : public Expression {
virtual float value() const {return val;}
float val;
};
struct AdditionOper : public Expression {
virtual float value() const {return lhs->value() + rhs->value();}
boost::shared_ptr<Expression> lhs;
boost::shared_ptr<Expression> rhs;
};
I'd start by parsing out the parenthesis, they will determine the order of your expressions. Then I'd split everything based on the numerical operands and start putting them in expressions. Then you're left with cases like 3 + 4 * 6 which would require some some care to get the order of operations right.
Good luck.
You can either run your function that converts a string representation of a number to a double and see if there's an error, or you can look at the contents of the string and see if it matches the pattern of a number and then do the conversion.
You might use boost::lexical_cast<double>() or std::stod() (C++11) where errors are reported with an exception, or istringstream extractors where the error is reported by setting the fail bit, or with C conversion functions that report errors by setting the global (thread local, rather) variable errno.
try {
istack.push_back(std::stod(aString));
} catch(std::invalid_argument &e) {
// aString is not a number
}
or
errno = 0;
char const *s = aString.c_str();
char *end;
double result = strtod(s,&end);
if(EINVAL==errno) {
// the string is not a number
} else {
istack.push_back(result);
}
An implementation of the second option might use a regex to see if the string matches the pattern you use for numbers, and if it does then running your conversion function. Here's an example of a pattern you might expect for floating point values:
std::regex pattern("[+-]?(\d*.\d+|\d+.?)([eE][+-]?\d+)?");
if(std::regex_match(aString,pattern)) {
istack.push_back(std::stod(aString));
} else {
// aString is not a number
}
Also, this probably doesn't matter to you, but most any built in method for converting a string to a number will be locale sensitive one way or another. One way to isolate yourself from this is to use a stringstream you create and imbue with the classic locale.
I guess the C++ (no boost) way would be this :
do
{
std::stringstream ss;
std::string test;
cin >> test;
ss << test;
int num;
if (ss >> num) // function to convert to read if int, convert to int
{
std::cout << "Number : " << num << "\n";
}
}while(true); // don't do this though..
Can you not use ctype.h http://www.cplusplus.com/reference/clibrary/cctype/. I have used this before and did not get into trouble.
Especially if you're doing base-10 input, I find the most blatant thing to do is read the string, then check that it only contains valid characters:
string s;
cin >> s;
if(strrspn(s.c_str(), "0123456789")==s.length()){
//int
} else{
//not int
}
Related
I am a C++ beginner,
#include <iostream>
int main()
{
char v1;
// valid no warning
std::cout << (std::cin >> v1) << std::endl; // return value of the expression expected
return 0;
}
// output: 1
// return value of the expression is 1?
Is the return value of (std::cin >> v1) really 1? Why?
I don't know of a current compiler that will accept your code as it stands right now. g++, clang and Microsoft all reject it, saying they can't find an overload to match the arguments (i.e., an operator<< for ostream that takes an istream as an operand).
It's possible to get the result you've posited with code on this order: std::cout << !!(std::cin >> v1) << "\n";. Depending on the age of the compiler and standard with which it complies, this does one of two things.
With a reasonably current compiler, this will use the Boolean conversion on the istream to get it to match the ! operator, then apply that (twice) to the result, so you write out the result of that operator.
With old enough compilers, there won't be a Boolean conversion operator, but there will be an overload of operator!, which also does a conversion to Boolean (but negated in sense, of course). The result of that will then be negated by the second !.
Either way, you end up writing out a Boolean value (or int containing zero or one on an old enough compiler) that indicates whether the stream is in a failed or successful state.
This is done to allow you to check input as you're reading it, so you can process input data sanely. For example, when/if you want to read all the values in a file, stopping at the end of the file, or when you encounter something that can't be interpreted as the desired type, you can write code on this general order:
// read integers from a file and print out their sum
int temp;
int total = 0;
while (std::cin >> temp) {
total += temp;
}
std::cout << total << "\n";
The while loop uses the conversion to Boolean to determine whether an attempt at reading a value was successful or not, so it continues reading values as long as that happens successfully, and quits immediately when reading is unsuccessful.
One common source of errors is to write a loop on this order instead:
while (std::cin.good()) { // or almost equivalently, check for end of file.
std::cin >> temp;
total += temp;
}
But loops like this get the sequence incorrect. One common symptom of the problem with this is that the last number in the file will be added to the total twice instead of once.
std::cin >> v1 returns cin; Not sure what type it gets converted to for std::cout, but most likely it indicates the state of cin, where 1 is good
Is the return value of (std::cin >> v1) really 1
No, see the ref for cin, it will return a istream.
Your codes will not work, we can not pass ::istream (std::cin) to operator<< of a std::ostream (std::cout).
Shoule be like the following:
char v1;
cout << "Input a char:";
cin >> v1;
The program only works for Pre-C++11 because the conversion to bool is not explicit.
Starting from C++11, the program will no longer work because the conversion to bool is explicit.
Note that std::cin >> v1; returns std::cin and not 1. But there is no operator<< for std::ostream that takes a std::cin.
The reason it works for Pre-C++11 is because in this case the conversion to bool was not explicit. But starting from C++11, the conversion to bool was made explicit and so the code no longer compiles.
For example,
bool b = std::cin; //WORKS for Pre-C++11 but FAILS for C++11 & onwards
bool b{std::cin}; //OK, WORKS for all versions(Pre-C++11 as well as C++11 & onwards) because in direct initialization we can use explicit conversion
I have a function that parses some input from std::cin and returns an integer value on success. I need to detect, based on the return value, if something went wrong when parsing input. Zero is a valid return. What can I use to differentiate between valid zero and "bad input"?
If I need to post code as an example, just let me know. Thanks!
[EDIT]
int parseInput(){
int calculatedValue = 0;
bool parseOk = true;
/* Parse cin for valid input.*/
if (parseOk) {
/* Perform calculation. Can be zero */
}
return calculatedValue; // Any integer is valid
}
This would be the perfect job for std::optional. Your best alternative, with regards to notify at return value, is to implement a similar class.
Alternatively, you should really use an exception. Exceptions are made exactly to notify the user of your function that something went wrong.
You can use an boolean flag for checking if something went wrong, it is common practice (for instance, Qt library uses it) to do something like:
int getIntegerStuffFromInput(bool & ok);
or
bool getIntegerStuffFromInput(int & value);
When you read numbers from std::cin, the most important thing is not to read directly into an int. Instead, you use std::getline to read a whole line of input into an std::string. This way you can detect wrong input much more easily.
Once the line has been entered, you convert the resulting std::string to an int.
std::string input_line;
std::getline(std::cin, input_line);
// input_line now contains a whole line of input
In C++11, you just use std::stoi for the conversion:
int const input = std::stoi(input_line);
This function will throw an exception if the string cannot be converted to an integer number.
In pre-C++11, you use std::istringstream:
std::istringstream is(input_line);
int input = 0;
is >> input;
The following code then checks if the line could be correctly converted to an integer number or not:
if (!is)
{
// error
}
"What can I use to differentiate between valid zero and "bad input"?"
You have basically three choices
If you need to handle all integers as a valid return value:
Throw an exception, that can be handled outside from your function call
Have a dedicated output parameter passed by reference, and return bool from your function, false indicates bad input.
If negative integers aren't a valid return value:
Just return a negative value and test for result < 0.
I have a string which can be either a double, float or int. I would like to convert the string to the data type by making function calls. I am currently using functions such as stof and stoi which throw exceptions when the input is not a float or int. Is there another way to convert the strings without having to catch exceptions? Perhaps some function that passes a a pointer to a float as argument and just returns a boolean which represents the success of the function of call. I would like to avoid using any try catch statements in any of my code.
Use a std::stringstream and capture the result of operator>>().
For example:
#include <string>
#include <iostream>
#include <sstream>
int main(int, char*[])
{
std::stringstream sstr1("12345");
std::stringstream sstr2("foo");
int i1(0);
int i2(0);
//C++98
bool success1 = sstr1 >> i1;
//C++11 (previous is forbidden in c++11)
success1 = sstr1.good();
//C++98
bool success2 = sstr2 >> i2;
//C++11 (previous is forbidden in c++11)
success2 = sstr2.good();
std::cout << "i1=" << i1 << " success=" << success1 << std::endl;
std::cout << "i2=" << i2 << " success=" << success2 << std::endl;
return 0;
}
Prints:
i1=12345 success=1
i2=0 success=0
Note, this is basically what boost::lexical_cast does, except that boost::lexical_cast throws a boost::bad_lexical_cast exception on failure instead of using a return code.
See: http://www.boost.org/doc/libs/1_55_0/doc/html/boost_lexical_cast.html
For std::stringstream::good, see: http://www.cplusplus.com/reference/ios/ios/good/
To avoid exceptions, go back to a time when exceptions didn't exist. These functions were carried over from C but they're still useful today: strtod and strtol. (There's also a strtof but doubles will auto-convert to float anyway). You check for errors by seeing if the decoding reached the end of the string, as indicated by a zero character value.
char * pEnd = NULL;
double d = strtod(str.c_str(), &pEnd);
if (*pEnd) // error was detected
Mark Ransom, you hit the nail on the head. I understand RagHaven because in certain situations exceptions are a nuisance, and converting alphanumeric chains to doubles should be something light and fast, not subject to the exception handling mechanism. I found that a five-alphanumeric string sorting algorithm took more than 3 seconds because exceptions were thrown in the process and somewhere in the software something was complaining.
In my search for conversion functions without launching exceptions I found this (I work with C++ Builder):
double StrToFloatDef(string, double def);
That function tries to return a float, and, if it does not succeed, instead of launching an exception it returns the value that is passed in the 2nd argument (which could for example be put to std::numeric_limits<double>::max()). Checking if the return value matches 'def' you can control the result without exceptions.
Mark's proposal, std::strtod, is just as good but much faster, standard and safe. A function like the one RagHaven asks for could look like this:
bool AsDouble(const char* s, double& v) const noexcept
{
char* pEnd = nullptr;
v = std::strtod(s, &pEnd);
return *pEnd == 0;
}
I'm having a annoying problem with a C++ function that I wrote and whose purpose is to validate de user input. The function reads the user input, verifies if it's a number and, if so, if it is in the range [min, max].
The problem occurs when I invoke the template function with a unsigned type, like size_t, and the input is a negative number. The string stream converts the string to something like 4294967291. I can see that the program is converting the data to a value near de maximum value of the unsigned data type (defined in the numeric_limits header) but my question is why, since the if statement should stop at sstream >> value?
My code:
template <class T>
T getNumberInput(std::string prompt, T min, T max) {
std::string input;
T value;
while (true) {
try {
std::cout << prompt;
std::cin.clear();
std::getline(std::cin, input);
std::stringstream sstream(input);
if (input.empty()) {
throw EmptyInput<std::string>(input);
} else if (sstream >> value && value >= min && value <= max) {
std::cout << std::endl;
return value;
} else {
throw InvalidInput<std::string>(input);
}
} catch (EmptyInput<std::string> & emptyInput) {
std::cout << "O campo não pode ser vazio!\n" << std::endl;
} catch (InvalidInput<std::string> & invalidInput){
std::cout << "Tipo de dados inválido!\n" << std::endl;
}
}
}
Thank you for your time!
In C++ arithmetic involving an unsigned type with n value bits, is guaranteed to be modulo 2^n. That means any result is wrapped back into the range 0 through 2^n-1, by adding or subtracting a suitable multiple of 2^n. This is so also in C.
So you need to check the input for minus sign, or add some other check.
By the way, your if with >> and && produced some effect on my bad-code-meter. I can never remember the operator precedences for >> versus &&. I guess if it compiled it must be OK, though, since >> can't take a value right-hand-side. Checking... OK, but I'd use parentheses to clarify that.
Also, on the code structure, it would be a good idea to separate the interactive input thing from the checking of the input. E.g., can you use any of that code in a GUI program, with input from an edit field? No, not as it is...
Cheers & hth.,
Alf has already answered this, but I had a couple of other thoughts.
Pull the code that gets the input out of the try block. You're not catching any exceptions that it might throw, so it doesn't communicate the intent as well. The try block should start right before the if (input.empty())...
Then pull all of the stuff in the try block into a single validate function. This cleans up the code here. For use in a GUI, though, you would want to create a function that just gets the input without validation and expose the validation function. Then the user could handle the validation exceptions as needed. Although in this case, I don't see an advantage to using exceptions as opposed to simple error codes for the validation.
Hope this helps,
In java, if I wanted to create some application which could receive both doubles and strings as appropriate input, I would probably do the following:
String input = getInput();//
try {
double foo = Double.valueOf(input);
//Do stuff with foo here
} catch (NumberFormatException e) {
//Do other validation with input
}
How would you go about doing that in c++? atof() returns 0.0 for invalid input, but how would you differentiate that from a valid double of "0.0"? As an aside, I can only include <iostream>, <string>, <cstdlib>, and <cassert> in this project. I'm assuming I need to use cin in some way, but how can you grab the original input after cin fails to parse some string as a double?
Edit: I could probably use the following, but as I said before, I'm not allowed to import <sstream> on this assignment for some reason
string input;
getline(cin, input);
double x;
istringstream foo(input);
foo >> x
if(cin){
//do manipulations with x
}
else{
//since it's not a number, check if input is a valid command etc..
}
Exceptions should be reserved for exceptional situations. While you certainly can abuse them like this, it's a lousy idea -- clearly you're pretty much expecting things other than doubles, so treating it as an exception doesn't make any real sense.
The only real question is the exact circumstance under which you want the input treated as a string. Just for example, if the input string was something like "1.23e2 non-numeric data", do you want to just use the "1.23e2" as a number, or do you want to treat the whole thing as a string?
Either way, you'd want to us strtod for the conversion -- the difference is only how you react to what it returns. In particular, strtod takes two parameters instead of just one like atof does. The second parameter is a pointer to pointer to char. Assuming you pass a non-NULL pointer, strtod will set it to point at the last character in the input string that it successfully converted. If it's pointing to the beginning of the input string, nothing was converted. If it's pointing to the end, everything was converted. If it's somewhere in between, part of the string converted, and part didn't.
For the moment, I'm going to assume that you want a double value holding whatever number could be converted at the beginning of the string, and whatever couldn't be converted treated as a string:
#include <stdlib.h>
#include <stdio.h>
int main() {
char input[] = "12.34 non-numeric data";
char *string;
double value = strtod(input, &string);
printf("Number: %f\tstring: %s\n", value, string);
return 0;
}
C++ streams associate the good, bad and fail state flags. These are stored in ios_base::goodbit, ios_base::badbit and ios_base::failbit respectively, but are commonly accessed through ios::good(), ios::bad() and ios::fail(). There's also ios_base::eofbit and ios::eof() but let's ignore that for the moment.
If parsing fails then the bad bit raises. Also, stream objects are convertible to a boolean-compatible type. If a stream is in a good state, then the statement
if( stream )
evaluates stream as true. Otherwise, it evaluates it as false. With this at hand, grabbing a value from standard input boils down to this:
#include <iostream>
// ...
double d = 0;
if ( std::cin >> d ) {
// input is a double. handle that here.
} else {
// input isn't a double. handle that here.
}
try "strtod" in stdlib.h
The C++ standard library seems to avoid exceptions for a lot of things that people might expect them, and this may not be the answer that you want to hear but parsing doubles isn't exactly rocket science so maybe it'd be ok to do it "by hand"?
One note if you do this, you'll probably want to collect it into an integer and then convert to a double and divide by 10^number_of_digits_after_decimal_point.
You could have a look at boost::lexical_cast, which would allow you to write pretty much the equivalent of the Java code:
string input;
getline(cin, input);
try {
double x = boost::lexical_cast<double>(input);
//Do manipulations with x
} catch (boost::bad_lexical_cast &) {
//Do other validation with input
}