Is it not reccomended to convert a string in such way:
string input = "81.312";
double val = atof(input.c_str());
DO NOT use std::atof in C++. That doesn't check for input error.
Use std::stod. That checks for error also and throws exception accordingly.
Also, it takes std::string const & as argument. So you don't have to pass input.c_str(). Just do this:
double value = std::stod(input);
It is not wrong, but more right would be to use boost::lexical_cast.
You should also check if these tools handle NANs and INFs correctly.
Related
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'm a novice programmer taking a c++ class.
The assignment is to write a double using stringstream, then check it using one of the macros in CppUnitLite. I want to use CHECK_DOUBLES_EQUAL to check the double in my write operation, but intellisense in VS says it wont' work. In the sample below, I've left what does work, a simple CHECK_EQUAL. This isn't good enough. I need to use CHECK_DOUBLES_EQUAL for floating point.
I've tried CHECK_DOUBLES_EQUAL(dvalue, svalue, 0.1) but that won't work. I've also tried using the actual value for expected, but that doesn't work either.
CHECK_DOUBLES_EQUAL does work for the read operation (second example), but I can't get it to work in the first.
Why is this? What am I doing wrong?
TEST(writeDouble, stringStream)
{
std::stringstream sValue;
double dvalue =34.9;
sValue << dvalue;
if (!sValue)
{
CHECK_FAIL("conversion failed");
}
CHECK_EQUAL("34.9", sValue.str());
}
TEST(readDouble, stringStream)
{
std::stringstream sValue("34.9");
double dvalue;
sValue >> dvalue;
if (!sValue)
{
CHECK_FAIL("conversion failed");
}
CHECK_DOUBLES_EQUAL(34.9, dvalue, 0.1);
}
The problem is that in your write operation, you aren't trying to compare against a double: You're trying to compare against a STRING. C++ is a statically typed language and won't compare a string to a double.
The code you're using with CHECK_EQUAL("34.9", sValue.str()); would appear to be the correct code to use to ensure that the stringstream correctly interpreted the input double value.
how can I convert a CString variable to a floating point?
(I'm using visuall c++ 6.0 and the MFC)
I'm trying to use an edit box to return a value which I'm putting into an array of floating points. I'm Using the GetWindowText method to get the value, which returns a CString. So I need to convert to a floating point. (or am I just doing things completely the wrong way?).
I presume there are methods for doing this already in the MFC.(have already used the Format method to convet to a CString display the values in the array in the edit box)
Thanks.
you can just do
CString pi = "3.14";
return atof(pi);
EDIT
Also use this function:
CString pi = "3.14";
return _ttof(pi);
Reading a string value and parse/convert it to float allows you to locate the error when there is one. All you need is a help of a C Run-time function: strtod() or atof().
I would prefer strtod as the second argument returns a pointer to the string where the parse terminated:
CString str;
m_edtMyEditBox.GetWindowText(str);
char *pEnd;
double dValue = strtod(str.GetBuffer(str.GetLength()), &pEnd);
if (*pEnd != '\0')
{
// Error in parsing
}
str.ReleaseBuffer();
How can i cast a pointer to char to a double ?
I am using command line arguments and one of the argument is a double but in the program is it passed as a char*.
I tried using static_cast and reinterpret_cast but with no effect.
Pure C++ solution:
#include <sstream>
// ...
std::stringstream ss;
ss << your_char_pointer;
ss >> your_double;
Boost solution:
#include <boost/lexical_cast.hpp>
// ...
your_double = boost::lexical_cast<double>(your_char_pointer);
Try Boost lexical_cast.
double val = atof(*charpointer)
atof stands for "all to float", (or "array to float"), and does exactly what you want. If it cannot convert the char array, it returns 0.0. See: Man atof
That's not how type conversion in C/C++ works. You must pass the string through a numeric parser manually. E.g.
char *thestring;
double d;
d = atof(thestring);
If the double comes from the command line, it is actually a real string, you have to convert it to a double, you can't just cast it.
For example, you can use strtod for this task :
double d = strtod (mystr,NULL);
You're trying to convert a string (represented by the char *) into a double. This is not something you can do with a regular built in type cast in C++ as all they do is reinterpret the bit pattern that is being referenced by the pointer. Instead you have to parse the command line argument to extract a double value from the string.
As mentioned, you have several options:
you can use atof for the conversion, but it's hard to determine if the conversion errored because both a string that can't be converted and one representing 0.0 give you the same result
As Fred Larson mentioned, you can use boost::lexical_cast. That's a pretty elegant way to handle the problem and would most likely be my preferred one
You can use iostreams to do the conversion
You can write the conversion code yourself (just kidding)
The atof man page says "The atof() function has been deprecated by strtod() and should not be used in new code."
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
}