Is there a safe standard way to convert std::string_view
to int
?
Since C++11 std::string
lets us use stoi
to convert to int
:
std::string str = "12345"; int i1 = stoi(str); // Works, have i1 = 12345 int i2 = stoi(str.substr(1,2)); // Works, have i2 = 23 try { int i3 = stoi(std::string("abc")); } catch(const std::exception& e) { std::cout << e.what() << std::endl; // Correctly throws 'invalid stoi argument' }
But stoi
does not support std::string_view
. So alternatively, we could use atoi
, but one has to be very careful, e.g.:
std::string_view sv = "12345"; int i1 = atoi(sv.data()); // Works, have i1 = 12345 int i2 = atoi(sv.substr(1,2).data()); // Works, but wrong, have i2 = 2345, not 23
So atoi
does not work either, since it is based off the null-terminator '\0'
(and e.g. sv.substr
cannot simply insert/add one).
Now, since C++17 there is also from_chars
, but it does not seem to throw when providing poor inputs:
try { int i3; std::string_view sv = "abc"; std::from_chars(sv.data(), sv.data() + sv.size(), i3); } catch (const std::exception& e) { std::cout << e.what() << std::endl; // Does not get called }
Using atoi() First, atoi() converts C strings (null-terminated character arrays) to an integer, while stoi() converts the C++ string to an integer. Second, the atoi() function will silently fail if the string is not convertible to an int , while the stoi() function will simply throw an exception.
Atoi is the fastest I could come up with. I compiled with msvc 2010 so it might be possible to combine both templates.
One effective way to convert a string object into a numeral int is to use the stoi() function. This method is commonly used for newer versions of C++, with is being introduced with C++11. It takes as input a string value and returns as output the integer version of it.
To convert from string representation to integer value, we can use std::stringstream. if the value converted is out of range for integer data type, it returns INT_MIN or INT_MAX. Also if the string value can't be represented as an valid int data type, then 0 is returned.
The std::from_chars function does not throw, it only returns a value of type from_chars_result
which is a struct with two fields:
struct from_chars_result { const char* ptr; std::errc ec; };
You should inspect the values of ptr
and ec
when the function returns:
#include <iostream> #include <string> #include <charconv> int main() { int i3; std::string_view sv = "abc"; auto result = std::from_chars(sv.data(), sv.data() + sv.size(), i3); if (result.ec == std::errc::invalid_argument) { std::cout << "Could not convert."; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With