Introduction : L'éternelle question "std::string en int"
\n\nBonjour, collègue programmeur ! Si vous avez déjà écrit un analyseur de configurations en C++, traité des entrées utilisateur ou extrait des nombres d'un fichier CSV, vous avez sûrement été confronté à la tâche : « Comment transformer une simple chaîne (std::string) en un nombre entier (int) ? ». Cela semble simple, n'est-ce pas ? Pourtant, en regardant sur Stack Overflow, vous verrez des milliers de votes et des dizaines de réponses différentes. Pourquoi ? Parce que derrière cette question simple se cache tout un monde de compromis entre convivialité, sécurité et performance.
Dans cet article, nous ne donnerons pas simplement une réponse sèche. Nous organiserons un véritable combat entre les principales méthodes de conversion : std::stoi, std::from_chars (C++17), std::stringstream, le bon vieux atoi, et nous écrirons même notre propre solution. Vous découvrirez quelle méthode choisir pour un serveur à forte charge, et laquelle pour un prototype rapide. C'est parti !
Méthode 1 : Le classique — std::stoi (C++11)
\n\nDepuis C++11, la bibliothèque standard propose une fonction élégante : std::stoi. Elle est simple, lisible et lève des exceptions en cas d'erreur. C'est le choix de 90 % des développeurs pour les tâches quotidiennes.
#include <iostream>\n#include <string>\n\nint main() {\n std::string number_str = "12345";\n try {\n int value = std::stoi(number_str);\n std::cout << "Nombre : " << value << std::endl;\n } catch (const std::invalid_argument& e) {\n std::cerr << "Erreur : la chaîne ne contient pas de nombre !" << std::endl;\n } catch (const std::out_of_range& e) {\n std::cerr << "Erreur : le nombre dépasse les limites de int !" << std::endl;\n }\n return 0;\n}\n\nAvantages et inconvénients de std::stoi
\n- \n
- Avantages : Simplicité, support des locales (reconnaît les virgules comme séparateurs), gestion automatique des erreurs via les exceptions. \n
- Inconvénients : Les exceptions coûtent cher. Si vous analysez des millions de nombres dans une boucle,
try-catchpeut considérablement ralentir le code. \n
Méthode 2 : Plus rapide que le vent — std::from_chars (C++17)
\n\nSi vous écrivez une application à forte charge où chaque nanoseconde compte, alors std::from_chars est votre héros. Cette fonction n'alloue pas de mémoire, ne lève pas d'exceptions et ne dépend pas de la locale. Elle convertit simplement les caractères en nombre et retourne un pointeur vers l'endroit où elle s'est arrêtée.
#include <iostream>\n#include <charconv>\n#include <string>\n#include <system_error>\n\nint main() {\n std::string number_str = "98765";\n int value = 0;\n auto [ptr, ec] = std::from_chars(number_str.data(), \n number_str.data() + number_str.size(), \n value);\n if (ec == std::errc()) {\n std::cout << "Nombre : " << value << std::endl;\n } else {\n std::cerr << "Erreur de conversion !" << std::endl;\n }\n return 0;\n}\n\nPourquoi from_chars est le roi de la performance ?
\n- \n
- Zero-overhead : Pas d'exceptions, pas d'allocations cachées. \n
- Localisation désactivée : Pas besoin de perdre du temps à vérifier les séparateurs décimaux. \n
- Retourne le reste de la chaîne : Idéal pour analyser les colonnes d'un CSV. \n
Selon les benchmarks, from_chars peut être 2 à 10 fois plus rapide que stoi, en particulier sur les chaînes courtes.
Méthode 3 : L'artillerie lourde — std::stringstream
\n\nDe nombreux programmeurs débutants utilisent std::stringstream pour la conversion. C'est un outil puissant, mais pour la tâche "chaîne en nombre", il est aussi excessif qu'un char pour aller acheter du pain.
#include <sstream>\n#include <string>\n#