What's the C++ way of parsing a string (given as char *) into an int? Robust and clear error handling is a plus (instead of returning zero).
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Correctly parse PDF paragraphs with Python
- Why does const allow implicit conversion of refere
- thread_local variables initialization
相关文章
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- How do I get from a type to the TryParse method?
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
I think these three links sum it up:
stringstream and lexical_cast solutions are about the same as lexical cast is using stringstream.
Some specializations of lexical cast use different approach see http://www.boost.org/doc/libs/release/boost/lexical_cast.hpp for details. Integers and floats are now specialized for integer to string conversion.
One can specialize lexical_cast for his/her own needs and make it fast. This would be the ultimate solution satisfying all parties, clean and simple.
Articles already mentioned show comparison between different methods of converting integers <-> strings. Following approaches make sense: old c-way, spirit.karma, fastformat, simple naive loop.
Lexical_cast is ok in some cases e.g. for int to string conversion.
Converting string to int using lexical cast is not a good idea as it is 10-40 times slower than atoi depending on the platform/compiler used.
Boost.Spirit.Karma seems to be the fastest library for converting integer to string.
and basic simple loop from the article mentioned above is a fastest way to convert string to int, obviously not the safest one, strtol() seems like a safer solution
I like Dan's answer, esp because of the avoidance of exceptions. For embedded systems development and other low level system development, there may not be a proper Exception framework available.
Added a check for white-space after a valid string...these three lines
Added a check for parsing errors too.
Here is the complete function..
I know this is an older question, but I've come across it so many times and, to date, have still not found a nicely templated solution having the following characteristics:
So, here is mine, with a test strap. Because it uses the C functions strtoull/strtoll under the hood, it always converts first to the largest type available. Then, if you are not using the largest type, it will perform additional range checks to verify your type was not over(under)flowed. For this, it is a little less performant than if one properly chose strtol/strtoul. However, it also works for shorts/chars and, to the best of my knowledge, there exists no standard library function that does that, too.
Enjoy; hopefully someone finds it useful.
StringToDecimal
is the user-land method; it is overloaded so it can be called either like this:or this:
I hate repeating the int type, so prefer the latter. This ensures that if the type of 'a' changes one does not get bad results. I wish the compiler could figure it out like:
...but, C++ does not deduce template return types, so that's the best I can get.
The implementation is pretty simple:
CstrtoxllWrapper
wraps bothstrtoull
andstrtoll
, calling whichever is necessary based on the template type's signed-ness and providing some additional guarantees (e.g. negative input is disallowed if unsigned and it ensures the entire string was converted).CstrtoxllWrapper
is used byStringToSigned
andStringToUnsigned
with the largest type (long long/unsigned long long) available to the compiler; this allows the maximal conversion to be performed. Then, if it is necessary,StringToSigned
/StringToUnsigned
performs the final range checks on the underlying type. Finally, the end-point method,StringToDecimal
, decides which of the StringTo* template methods to call based on the underlying type's signed-ness.I think most of the junk can be optimized out by the compiler; just about everything should be compile-time deterministic. Any commentary on this aspect would be interesting to me!
This is a safer C way than atoi()
C++ with standard library stringstream: (thanks CMS )
With boost library: (thanks jk)
Edit: Fixed the stringstream version so that it handles errors. (thanks to CMS's and jk's comment on original post)
The good 'old C way still works. I recommend strtol or strtoul. Between the return status and the 'endPtr', you can give good diagnostic output. It also handles multiple bases nicely.
I like Dan Moulding's answer, I'll just add a bit of C++ style to it:
It works for both std::string and const char* through the implicit conversion. It's also useful for base conversion, e.g. all
to_int("0x7b")
andto_int("0173")
andto_int("01111011", 2)
andto_int("0000007B", 16)
andto_int("11120", 3)
andto_int("3L", 34);
would return 123.Unlike
std::stoi
it works in pre-C++11. Also unlikestd::stoi
,boost::lexical_cast
andstringstream
it throws exceptions for weird strings like "123hohoho".NB: This function tolerates leading spaces but not trailing spaces, i.e.
to_int(" 123")
returns 123 whileto_int("123 ")
throws exception. Make sure this is acceptable for your use case or adjust the code.Such function could be part of STL...