c++ - parse - ¿Cómo puedo convertir un std:: string a int?
parse int c++ (11)
¿Qué hay de Boost.Lexical_cast ?
Aquí está su ejemplo:
El siguiente ejemplo trata los argumentos de la línea de comandos como una secuencia de datos numéricos:
int main(int argc, char * argv[])
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
std::vector<short> args;
while(*++argv)
{
try
{
args.push_back(lexical_cast<short>(*argv));
}
catch(bad_lexical_cast &)
{
args.push_back(0);
}
}
...
}
Sólo tienes una pregunta rápida. He mirado un poco por Internet y he encontrado algunas soluciones, pero ninguna de ellas ha funcionado todavía. En cuanto a convertir una cadena a un int, no me refiero a los códigos ASCII.
Para una reducción rápida, se nos pasa en una ecuación como una cadena. Debemos descomponerlo, formatearlo correctamente y resolver las ecuaciones lineales. Ahora, al decir eso, no puedo convertir una cadena a un int.
Sé que la cadena tendrá el formato (-5) o (25), etc. así que definitivamente es un int. Pero, ¿cómo extraemos eso de una cuerda?
Una forma en la que estaba pensando es ejecutar un bucle for / while a través de la cadena, buscar un dígito, extraer todos los dígitos después de eso y luego ver si había un ''-'' inicial, si existe, multiplicar el int por 1.
Sin embargo, parece un poco más complicado para un problema tan pequeño. ¿Algunas ideas?
En C ++ 11 hay algunas nuevas y agradables funciones de conversión de std::string
a un tipo de número.
Así que en lugar de
atoi( str.c_str() )
puedes usar
std::stoi( str )
donde str
es tu número como std::string
.
Hay versiones para todos los tipos de números: long stol(string)
, float stof(string)
, double stod(string)
, ... vea http://en.cppreference.com/w/cpp/string/basic_string/stol
En Windows, puedes usar:
const std::wstring hex = L"0x13";
const std::wstring dec = L"19";
int ret;
if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "/n";
}
if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "/n";
}
strtol
, stringstream
necesita especificar la base si necesita interpretar hexdecimal.
Es cierto que mi solución no funcionaría con enteros negativos, pero extraerá todos los enteros positivos del texto de entrada que contiene enteros. Hace uso de locale numeric_only
:
int main() {
int num;
std::cin.imbue(std::locale(std::locale(), new numeric_only()));
while ( std::cin >> num)
std::cout << num << std::endl;
return 0;
}
Texto de entrada:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878
Enteros de salida:
5
25
7987
78
9878
La clase numeric_only
se define como:
struct numeric_only: std::ctype<char>
{
numeric_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc[''0''], &rc['':''], std::ctype_base::digit);
return &rc[0];
}
};
Demostración en línea completa: http://ideone.com/dRWSj
Esto normalmente funciona cuando lo uso:
int myint = int::Parse(mystring);
Las posibles opciones se describen a continuación:
1. Primera opción: sscanf ()
#include <cstdio>
#include <string>
int i;
float f;
double d;
std::string str;
// string -> integer
if(sscanf(str.c_str(), "%d", &i) != 1)
// error management
// string -> float
if(sscanf(str.c_str(), "%f", &f) != 1)
// error management
// string -> double
if(sscanf(str.c_str(), "%lf", &d) != 1)
// error management
Esto es un error (también se muestra con cppcheck) porque "scanf sin límites de ancho de campo puede bloquearse con datos de entrada enormes en algunas versiones de libc" (consulte here y here ).
2. Segunda opción: std :: sto * ()
#include <iostream>
#include <string>
int i;
float f;
double d;
std::string str;
try {
// string -> integer
int i = std::stoi(s);
// string -> float
float f = std::stof(s);
// string -> double
double d = std::stod(s);
} catch (...) {
// error management
}
Esta solución es breve y elegante, pero está disponible solo en compiladores que cumplan con C ++ 11.
3. Tercera opción: sstreams
#include <string>
#include <sstream>
int i;
float f;
double d;
std::string str;
// string -> integer
std::istringstream ( str ) >> i;
// string -> float
std::istringstream ( str ) >> f;
// string -> double
std::istringstream ( str ) >> d;
// error management ??
Sin embargo, con esta solución es difícil distinguir entre una entrada incorrecta (consulte here ).
4. Cuarta opción: Boost''s lexical_cast.
#include <boost/lexical_cast.hpp>
#include <string>
std::string str;
try {
int i = boost::lexical_cast<int>( str.c_str());
float f = boost::lexical_cast<int>( str.c_str());
double d = boost::lexical_cast<int>( str.c_str());
} catch( boost::bad_lexical_cast const& ) {
// Error management
}
Sin embargo, esto es solo una envoltura de sstream, y la documentación sugiere usar sstrem para una mejor gestión de errores (consulte here ).
5. Quinta opción: strto * ()
Esta solución es muy larga, debido a la gestión de errores, y se describe aquí. Como ninguna función devuelve un int simple, se necesita una conversión en el caso de un entero (consulte here cómo se puede lograr esta conversión).
6. Sexta opción: Qt
#include <QString>
#include <string>
bool ok;
std::string;
int i = QString::fromStdString(str).toInt(&ok);
if (!ok)
// Error management
float f = QString::fromStdString(str).toFloat(&ok);
if (!ok)
// Error management
double d = QString::fromStdString(str).toDouble(&ok);
if (!ok)
// Error management
Conclusiones
En resumen, la mejor solución es C ++ 11 std :: stoi () o, como segunda opción, el uso de bibliotecas Qt. Todas las demás soluciones son desalentadas o con errores.
Probablemente sea un poco excesivo, pero boost::lexical_cast<int>( theString )
debería funcionar bastante bien.
hay otra manera fácil: suponga que tiene un carácter como c=''4''
por lo tanto, puede hacer uno de estos pasos:
1: int q
q=(int) c ; (q is now 52 in ascii table ) . q=q-48; remember that adding 48 to digits is their ascii code .
la segunda forma:
q=c-''0''; the same , character ''0'' means 48
use la función atoi para convertir la cadena en un entero:
string a = "25";
int b = atoi(a.c_str());
atoi
es una función incorporada que convierte una cadena en un entero, asumiendo que la cadena comienza con una representación entera.
std::istringstream ss(thestring);
ss >> thevalue;
Para ser completamente correcto querrá comprobar los indicadores de error.