Tengo un problema extraño sobre trabajar con enteros en C ++.
Escribí un programa simple que establece un valor en una variable y luego lo imprime, pero no funciona como se esperaba.
Mi programa solo tiene dos líneas de código:
uint8_t aa = 5;
cout << "value is " << aa << endl;
La salida de este programa es value is
Es decir, se imprime en blanco para aa.
Cuando cambio uint8_tal uint16_tcódigo anterior funciona como un encanto.
Yo uso Ubuntu 12.04 (Precise Pangolin), 64 bits, y mi versión del compilador es:
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

Respuestas:
Realmente no imprime un espacio en blanco, pero probablemente el carácter ASCII con valor 5, que no es imprimible (o invisible). Hay una serie de códigos de caracteres ASCII invisibles , la mayoría de ellos por debajo del valor 32, que en realidad es el espacio en blanco.
Debe convertir
aaaunsigned intpara generar el valor numérico, ya queostream& operator<<(ostream&, unsigned char)intenta generar el valor del carácter visible.fuente
int. Un reparto es una forma de hacerlo, pero no la única.+aaTambién funciona.int(var)y(int)vartienes exactamente el mismo significado.int(var)se desaconseja exactamente en aquellos casos en que(int)vares, por exactamente las mismas razones, porque significa exactamente lo mismo. (Puedo entender por qué te gustaría ir a por ello aquí de todos modos, aunque, por lo que no estoy diciendo que necesita para su usostatic_castsólo creo el rastro comentario aquí tiene un poco innecesariamente confuso..)uint8_tprobablemente será untypedefparaunsigned char. Laostreamclase tiene una sobrecarga especial paraunsigned char, es decir, imprime el carácter con el número 5, que no es imprimible, de ahí el espacio vacío.fuente
Agregar un operador unario + antes de la variable de cualquier tipo de datos primitivo dará un valor numérico imprimible en lugar del carácter ASCII (en el caso del tipo char).
fuente
uint8_tcomounsigned charcuáles serían valores numéricos?uint8_tes solo un tipo defunsigned char,unsigned charse maneja de laostreammisma manerachare imprime su valor ASCII.unsigned charque explica mucho. Entonces el único número entero esint, ¿verdad?short intque ocupa 2 bytes. También hay algunas otras variaciones del tipo entero.longointporque el compilador optimizaría el uso de RAM o flash de acuerdo con lo que llena ese registro, ¿estoy en lo cierto?Esto se debe a que el operador de salida trata el a
uint8_tcomochar(uint8_tgeneralmente es solo un aliasunsigned char), por lo que imprime el carácter con el código ASCII (que es el sistema de codificación de caracteres más común)5.Ver, por ejemplo, esta referencia .
fuente
signedy losunsignedcaracteres (más allá de lo simple,charque en C ++ es realmente un tercer tipo separado). Entonces, siuint8_tes un alias paraunsigned char(muy probable), eso es lo que se usará.Haciendo uso de ADL (búsqueda de nombre dependiente del argumento):
salida:
También sería posible un manipulador de flujo personalizado.
cout << +i << endl).fuente
return std::is_signed<char>::value ? os << static_cast<int>(c) : os << static_cast<unsigned int>(c);coutse trataaacomo uncharvalor ASCII5que es un carácter no imprimible, intente la conversión de textointantes de imprimir.fuente
los
operator<<()sobrecarga entreistreamychares una función no miembro. Puede usar explícitamente la función miembro para tratar achar(o auint8_t) como unint.Salida:
fuente
Como otros dijeron antes, el problema ocurre porque el flujo estándar trata los caracteres con signo y los caracteres sin signo como caracteres únicos y no como números.
Aquí está mi solución con cambios mínimos de código:
Agregando
"+0"es seguro con cualquier número, incluido el punto flotante.Para los tipos enteros, cambiará el tipo de resultado a
intifsizeof(aa) < sizeof(int). Y no cambiará el tipo sisizeof(aa) >= sizeof(int).Esta solución también es buena para prepararse
int8_tpara imprimirse en streaming, mientras que otras soluciones no son tan buenas:Salida:
La solución PS con ADL dada por pepper_chico y πάντα ῥεῖ es realmente hermosa.
fuente