Y a-t-il un standard de sécurité façon de convertir std::string_view
à int
?
Depuis C++ 11 std::string
nous permet d'utiliser stoi
pour convertir en 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'
}
Mais stoi
ne supporte pas std::string_view
. Donc, alternativement, nous pourrions utiliser atoi
, mais il faut faire très attention, par exemple:
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
Donc, atoi
ne fonctionne pas non plus, car il est basé sur le terminateur null '\0'
(et par exemple sv.substr
ne peut pas simplement insérer/ajouter un).
Maintenant, depuis C++ 17 il y a aussi from_chars
, mais il ne semble pas joindre lors de la fourniture de mauvaises intrants:
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
}
Immeuble sur @ron et @ Holt's excellentes réponses, voici une petite wrapper autour de std::from_chars()
qui renvoie une option (std::nullopt
Lorsque l'entrée ne parvient pas à analyser).
#include <charconv>
#include <optional>
#include <string_view>
std::optional<int> to_int(const std::string_view & input)
{
int out;
const std::from_chars_result result = std::from_chars(input.data(), input.data() + input.size(), out);
if(result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range)
{
return std::nullopt;
}
return out;
}