web-dev-qa-db-fra.com

Convertir en toute sécurité STD :: string_view sur INT (comme Stoi ou Atoi)

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
  }
14
Phil-ZXX

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;
}
0
s3cur3