Introducción: La eterna pregunta "std::string a int"
\n\n¡Hola, colega programador! Si alguna vez has escrito en C++ un analizador de configuraciones, has procesado entrada de usuario o has extraído números de un archivo CSV, seguramente te has enfrentado a la tarea: «¿Cómo convertir una cadena normal (std::string) en un número entero (int)?». Parecería que no podría ser más sencillo. Sin embargo, al mirar en Stack Overflow, verás miles de votos y docenas de respuestas. ¿Por qué? Porque detrás de esta simple pregunta se esconde un mundo de compromisos entre conveniencia, seguridad y rendimiento.
En este artículo no solo daremos una respuesta seca. ¡Organizaremos una verdadera batalla entre los métodos principales de conversión: std::stoi, std::from_chars (C++17), std::stringstream, el viejo y querido atoi e incluso escribiremos nuestra propia solución casera. Descubrirás qué método elegir para un servidor de alta carga y cuál para un prototipo rápido. ¡Allá vamos!
Método 1: El clásico — std::stoi (C++11)
\n\nA partir de C++11, la biblioteca estándar incluye la elegante función std::stoi. Es simple, legible y lanza excepciones en caso de errores. Es la elección del 90% de los desarrolladores para tareas cotidianas.
#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 << "Número: " << value << std::endl;\n } catch (const std::invalid_argument& e) {\n std::cerr << "Error: ¡la cadena no contiene un número!" << std::endl;\n } catch (const std::out_of_range& e) {\n std::cerr << "Error: ¡el número está fuera del rango de int!" << std::endl;\n }\n return 0;\n}\n\nVentajas y desventajas de std::stoi
\n- \n
- Ventajas: Simplicidad, soporte de configuraciones regionales (reconoce comas como separadores), manejo automático de errores mediante excepciones. \n
- Desventajas: Las excepciones son costosas. Si analizas millones de números en un bucle,
try-catchpuede ralentizar significativamente el código. \n
Método 2: Más rápido que el viento — std::from_chars (C++17)
\n\nSi escribes una aplicación de alta carga donde cada nanosegundo cuenta, entonces std::from_chars es tu héroe. Esta función no asigna memoria, no lanza excepciones y no depende de la configuración regional. Simplemente convierte caracteres en un número y devuelve un puntero al lugar donde se detuvo.
#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 << "Número: " << value << std::endl;\n } else {\n std::cerr << "¡Error de conversión!" << std::endl;\n }\n return 0;\n}\n\n¿Por qué from_chars es el rey del rendimiento?
\n- \n
- Zero-overhead: Sin excepciones, sin asignaciones ocultas. \n
- Localización desactivada: No es necesario perder tiempo verificando separadores decimales. \n
- Devuelve el resto de la cadena: Ideal para analizar columnas en CSV. \n
Según los benchmarks, from_chars puede ser de 2 a 10 veces más rápido que stoi, especialmente en cadenas cortas.
Método 3: Artillería pesada — std::stringstream
\n\nMuchos programadores principiantes usan std::stringstream para la conversión. Es una herramienta poderosa, pero para la tarea de "cadena a número" es excesiva, como un tanque para ir a la tienda a comprar pan.
#include <sstream>\n#include <string>\n#