2010-12-18 11 views
10

Al utilizar scanf() y sus variantes, el especificador de formato %i aceptará los datos como hexadecimales (prefijado "0x"), octal (prefijado "0") o decimal (sin prefijo), por ejemplo, las cadenas "0x10" , "020" y "16" se convierten todos a un número entero con un valor decimal 16.¿Puede `std :: istream :: operator >>()` aceptar los prefijos de raíz entera como el especificador de formato% i de stdio?

¿Se puede hacer esto con la entrada formateada std::istream::operator>>?

Usando llanura >> i sin i/o manipulador "0x10" se convierte en cero (o más bien el 0 es decir, la parte "x10" no se procesa), y "020" a 20. El hex, oct y Los manipuladores dec se comportan como %x, %o y %d respectivamente. Estoy buscando un manipulador de entrada entero general que funcione como %i.

Curiosamente, quizás el manipulador hex acepta tanto "0x10" como "10" convirtiendo a 16 decimales.

En caso de que se lo esté preguntando, estoy implementando un evaluador de expresiones, y me gustaría que los operandos enteros permitidos fueran hexadecimales, octales o decimales usando la convención de prefijos C/C++. La implementación actual que usa sscanf() hace esto automáticamente usando %i, y tengo curiosidad acerca de si esto podría modificarse para usar iostream sin tener que analizar explícitamente el formato numérico.

+0

interestin. +1. Me pregunto si el libro de C++ IOStreams y Locales tiene este tipo de cosas ... –

+0

Dado que estoy casi 100% seguro de que no existe un equivalente directo, creo que la solución más conveniente y más útil sería implementar un nuevo manipulador de la forma 'std :: ios_base & integer (std :: ios_base & str);' – Clifford

+0

@Johannes tiene la respuesta, que también proporciona los medios para implementar el manipulador anterior. – Clifford

Respuesta

10

El campo base en los indicadores de formato de basic_istream dicta cómo interpretar los números. El campo se puede establecer en dec, oct y en hex. Por defecto está configurado en dec. Si se establece en ninguno de ellos, basic_istream se comportará como %i bandera scanf 's:

// automatically detect the base, depending on prefix 
std::cin.unsetf(std::ios_base::basefield); 
+0

Genius. Ahora que veo cómo se hace, es mucho más fácil encontrar la documentación que le dice cómo hacerlo. por ejemplo: http://stdcxx.apache.org/doc/stdlibug/28-3.html – Clifford

Cuestiones relacionadas