std::String
std::String
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
(\__/)
(='.'=) Copy bunny into your signature to
(")_(") help him gain world domination.
(='.'=) Copy bunny into your signature to
(")_(") help him gain world domination.
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;
The difference is the std::stringstream uses a locale which will leak memory like a sieve with some versions of the Dinkumware C++ Standard C++ Library [like the one that ships with VC7]. Personally, I prefer the C library calls for data conversion. atoi, sscanf or strtol. They don't involve making a temporary copy of the data like std::stringstream does. But that is just me. :)
Travis
Travis
@ vitek
But all the C library calls you mentioned are not type safe.
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. C++ stringstream is type safe and actually the
BOOST::numeric_cast use it as underlying implementation.
When bad cast or overflow occurs, BOOST::numeric_cast
will throw bad_numeric_cast and overflow exceptions for
us and we still have chance for a possible recovery. Even
if BOOST is too heavy we can still learn the basic idea
from it.
->
http://www.boost.org/libs/numeric/conve ... meric_cast
For OP's problem, IMHO, no one single solution fits all
situations. If type-safe is not an issue, C library call
maybe is the better choice.
BTW, for number cast, usually we use std::ostringstream
instead of std::stringstream, and the std::ostringstream does
not have the problem you mentioned, well, IIRC.
But all the C library calls you mentioned are not type safe.
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. C++ stringstream is type safe and actually the
BOOST::numeric_cast use it as underlying implementation.
When bad cast or overflow occurs, BOOST::numeric_cast
will throw bad_numeric_cast and overflow exceptions for
us and we still have chance for a possible recovery. Even
if BOOST is too heavy we can still learn the basic idea
from it.
->
http://www.boost.org/libs/numeric/conve ... meric_cast
For OP's problem, IMHO, no one single solution fits all
situations. If type-safe is not an issue, C library call
maybe is the better choice.
BTW, for number cast, usually we use std::ostringstream
instead of std::stringstream, and the std::ostringstream does
not have the problem you mentioned, well, IIRC.
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);
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
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, I said it is possible that the bad cast will
casue program crash since the wrong/unexcepted result can not
be handled correctly by client code. With a unexcepted 0 in hand,
tell me what will you do next?
No, 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.
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
BOOST::lexcial_cast, I apologize for the possible confusion.
And if you want to discuss the typesafe/unsafe number cast,
we can go to lang.c++.moderate.
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, strtol, strtod, ...] to write them.
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
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
Last edited by vitek on Mon Apr 16, 2007 1:25 am, edited 1 time in total.
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
Nothin' but love Vitek .
vitek wrote:I don't know how much you know about the iostreams, but I'll let you in on a little secret.
How much I know about the iostream is not that important,
just show your points here, no mater it is so-called "secret"
or not. Making unnecessary assumption is meaningless.
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.
You totally missed the point here in my mind.
To repeat myself again, I am talking about the type-safe issues
here. The type-safe conversion provides a way for possible
recovery from bad cast, which is not available for the old
C library calls.
And, the particular standard library implementation which leaks
memory is an different (well, related) issue. As to the leak issue,
it is because some implementation (Vs2005 without SP1) failed
to handle multi-inheritance correctly, and as I said in the very
beginning, using std::ostringstream (does not have MI problem)
for conversion will solve the problem.
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
use it or not ?
Instead of keep from using your C++ iostream, you can simply
1. Get the latest service pack (Vs2005 SP1, for example),
which solved the problem already.
2. Stay with ostringstream for the string-number conversion.
Of course, actually I do not care which method will you use,
I just want to show my point when we do string-number
conversions. That's all.
BTW, words like BULL**** won't help at all in technical discussion
here, English is not my native language but I am sure you can find
other, better way to express your idea/point.
Jiang
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.
You also missed one of my points. 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. That is not to mention the problem with the leaking streams.
In addition, using std::ostringstream only solves the type safe problem. It does nothing for underflow or overflow.
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.
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
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.
Roger that, I said if type safe is not an issue, then C library calls
are just fine. No problem here.
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]
Yes, using the std::ostringstream will cause a temp object creation
and destruction, which costs a little bit more, compared with the
C library calls ( raw pointer operations ). However, it provides a
safe method and it is possible for us to find the design balance here:
fast, non-recovery method or prepare for the possible recovery.
No one single method fits all needs.
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.
can not detect the underflow or overflow.
But I think it is possible to learn from BOOST::numeric_cast and
build our own string-number converter, well, if the cost is not
an issue.
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?
I doubt they are in same situation.
For atoi, according to the C99 standard (7.20.1 p1),
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.
Well, Hybrid, even you and I don't have to post for the post to get out of hand!!!
I was simply going to point out, that it's faster to compare the number and the number generated from atoi, then it was to convert to a string, and then do a string comparison.
But I like Vitek's and Jihang's argument better. They are more lively than us as well!!!
I was simply going to point out, that it's faster to compare the number and the number generated from atoi, then it was to convert to a string, and then do a string comparison.
But I like Vitek's and Jihang's argument better. They are more lively than us as well!!!