std::String
Posted: Sat Apr 14, 2007 2:25 pm
Hello all
how can i compare a std::string to a number , whith out getting an error???
thx
how can i compare a std::string to a number , whith out getting an error???
thx
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
Code: Select all
std::string numStr;
int cmpNum;
if( atoi( numStr.c_str() ) == cmpNum )
std::cout << "numStr equals cmpNum" << std::end;
else
std::cout << "numStr DOES NOT EQUAL cmpNum" << std::end;
Bull****. Apparently you don't know the C library very well. The results are well defined for all of the C data conversion functions. If the input string is not a number, atoi returns 0, but there is no indicator for under or overflow. strtol returns 0 on under/overflow and sets the output parameter to the character that ended the scan. sscanf returns the number of conversions applied, so if you are scanning just one token and you get a value other than one, then something went wrong. You can try it for yourself...That means, if the string can not be convert/cast to a number, it is quite possible that the program will crash for the bad data casted.
Code: Select all
static const char nan[] = "not a number";
// none of these lines crash when you pass a non-numeric string
int i = atoi(nan);
long l = strtol(nan, 0, 10);
int c = sscanf(nan, "%d", &i);
Oops, what do you mean here? If you want to say it, then just say it out.vitek wrote:Bull****.That means, if the string can not be convert/cast to a number, it is quite possible that the program will crash for the bad data casted.
Apparently you did not get my point.vitek wrote:
Apparently you don't know the C library very well. The results are well defined for all of the C data conversion functions. If the input string is not a number, atoi returns 0, but there is no indicator for under or overflow. strtol returns 0 on under/overflow and sets the output parameter to the character that ended the scan. sscanf returns the number of conversions applied, so if you are scanning just one token and you get a value other than one, then something went wrong. You can try it for yourself...
In my previous post, the BOOST::numeric_cast should readvitek wrote:
I do agree hat the sscanf function is not type safe. You can pass a conversion string %d but pass an argument that is not of type int and that might cause a crash.
Also, the boost::numeric_cast template is not for converting strings to numbers, it is for converting one numeric type to another [i.e. 8-bit int to 16-bit int] and back and detecting overflow/underflow errors because of these conversions. The implementation does not use std::stringstream in any way, shape or form. It doesn't even use a single class from the lib.iostream part of the Standard C++ Library.
Travis
vitek wrote:I don't know how much you know about the iostreams, but I'll let you in on a little secret. The stream classes use locale for formatting data. The locale has a facet for getting and putting numeric types into a stream [num_put and num_get]. Several of the Standard C++ Library implementations I've looked at use the Standard C Library data conversion routines [[sprintf[/i], strtol, strtod, ...] to write them.
Travis
vitek wrote:I don't know how much you know about the iostreams, but I'll let you in on a little secret.
vitek wrote: The stream classes use locale for formatting data. The locale has a facet for getting and putting numeric types into a stream [num_put and num_get]. Several of the Standard C++ Library implementations I've looked at use the Standard C Library data conversion routines [sprintf, strtol, strtod, ...] to write them.
Sound like FUD for me, Irrlicht also has bug reported, do youvitek wrote:
I still stand by my original comments. The stream classes on some versions of the C++ library leak like a sieve, and I prefer to just use the C library data conversion routines.
Travis
And I'm ignoring the type safety issues. There is no type safety issue if you want to convert a string to an long using strtol. The type safety issue only appears when you want to write code independent of the type and have it work correctly. If this is the case, throw a template specialization around a call to strtol.I am talking about the type-safe issues here.
Well, you would write code to do some error checking. The same exact thing you would do if lexical_cast threw a bad_lexical_cast exception. I mean you would have to write at least 4 lines of code to catch and process the exception, you can check for an error from strtol just as easily.With a unexcepted 0 in hand, tell me what will you do next?
If you can't expect the client code to do proper error checking on the result of a C function call, can you expect it to be exception safe?C library calls themselves wont crash your problem, they are designed to do their job, but I wonder the client code can do the same job.
vitek wrote:
And I'm ignoring the type safety issues. There is no type safety issue if you want to convert a string to an long using strtol. The type safety issue only appears when you want to write code independent of the type and have it work correctly. If this is the case, throw a template specialization around a call to strtol.
Partly true in my mind.vitek wrote:
[snip]
Using the stringstream to convert a string to an integer involves an additional, and unnecessary memory allocation and string copy. Call me an unnecessary optimizer.
[snip]
This is true. Without numeric limits checking, even BOOST::lexical_castvitek wrote:
In addition, using std::ostringstream only solves the type safe problem. It does nothing for underflow or overflow.
vitek wrote:Well, you would write code to do some error checking. The same exact thing you would do if lexical_cast threw a bad_lexical_cast exception. I mean you would have to write at least 4 lines of code to catch and process the exception, you can check for an error from strtol just as easily.With a unexcepted 0 in hand, tell me what will you do next?
7.20.1 Numericconversion functions
1 The functions atof, atoi, atol, and atoll need not affect the value of the
integer expression errno on an error.Ifthe value of the result cannot
be represented, the behavior is undefined.
[end quote C99]
Here undefined behavior means the compiler can do whatever it like:
return 0 for you, or format your harddisk immediately.
I am not language lawer, but I would like to say the above situation is
quite serious and even some implementations will return an
not-so-meaningful integer for you, it is still an QoS and C/C++
language do not guarantee this behavior at all.
And, even we are lucky enough that all compilers we use do return a
0 when bad cast occurred, it is still difficult to do error checking/handling
using C library calls. For example, what about if the string we used is
exactly "0"?
Here i and j are possible both 0, for this case, we can not tell apartCode: Select all
int i = atoi("0"); int j = atoi("xxxxDEADBEEFxxxx");
whether bad cast occurred or not.
For the above reason, the C/C++ language just make it undefined
behavior and who wrote the bad cast code will be responsible for the
possible consequences.
vitek wrote:If you can't expect the client code to do proper error checking on the result of a C function call, can you expect it to be exception safe?C library calls themselves wont crash your problem, they are designed to do their job, but I wonder the client code can do the same job.
For above reason, IMHO, it is near to impossible to do practical systematical error number conversion checking using C library calls.
Since one of the spirits of C language is "Trust the programmer",
here nothing strange at all. However, compared with C language,
C++'s 's typing system was improved quite a lot to avoid such kind of problems.
No problem.vitek wrote:
The bottom line is that I misunderstood your original post, probably because of our language issues. And then I jumped down your throat for saying things that you hadn't actually said. For that, I appologize.
Travis
I read my OP again and I realized that my points were not so clear
at the first glance. Sorry for that, I wish I had made my points clearer.