c++ - sirve - uint8_t no se puede imprimir con cout
que significa endl en c++ (8)
Agregar un operador unario + antes de la variable de cualquier tipo de datos primitivos dará valor numérico imprimible en lugar de caracteres ASCII (en el caso del tipo de caracteres).
uint8_t aa=5;
cout<<"value is "<< +aa <<endl;
Tengo un problema extraño sobre trabajar con enteros en C ++.
Escribí un programa simple que establece un valor para una variable y luego la imprime, pero no está funcionando como se esperaba.
Mi programa tiene solo dos líneas de código:
uint8_t aa = 5;
cout << "value is " << aa << endl;
El resultado de este programa es el value is
Es decir, imprime en blanco para aa
.
Cuando cambio uint8_t
por uint16_t
el código anterior funciona como un amuleto.
Uso Ubuntu 12.04 (Precise Pangolin), de 64 bits, y mi versión del compilador es:
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Como otros dijeron antes, el problema ocurre porque la transmisión estándar trata a los caracteres con signo y sin signo como caracteres únicos y no como números.
Aquí está mi solución con cambios mínimos de código:
uint8_t aa = 5;
cout << "value is " << aa + 0 << endl;
Agregar "+0"
es seguro con cualquier número, incluido el punto flotante.
Para tipos enteros, cambiará el tipo de resultado a int
si sizeof(aa) < sizeof(int)
. Y no cambiará de tipo si sizeof(aa) >= sizeof(int)
.
Esta solución también es buena para preparar int8_t
para que se imprima en streaming, mientras que otras soluciones no son tan buenas:
int8_t aa = -120;
cout << "value is " << aa + 0 << endl;
cout << "bad value is " << unsigned(aa) << endl;
Salida:
value is -120
bad value is 4294967176
La solución PS con ADL dada por pepper_chico y πάντα ῥεῖ es realmente hermosa.
La sobrecarga del operator<<()
entre istream
y char
es una función no miembro. Puede usar explícitamente la función de miembro para tratar un char
(o un uint8_t
) como int
.
#include <iostream>
#include <cstddef>
int main()
{
uint8_t aa=5;
std::cout << "value is ";
std::cout.operator<<(aa);
std::cout << std::endl;
return 0;
}
Salida:
value is 5
Realmente no imprime un espacio en blanco, pero muy probablemente el carácter ASCII con valor 5, que es invisible. Hay una serie de códigos invisibles de caracteres ASCII , la mayoría de ellos por debajo del valor 32, que es el espacio en blanco en realidad.
ostream& operator<<(ostream&, unsigned char)
convertir aa
en unsigned int
para generar el valor numérico, ya que ostream& operator<<(ostream&, unsigned char)
intenta generar el valor del carácter visible.
uint8_t aa=5;
cout << "value is " << unsigned(aa) << endl;
Se debe a que el operador de salida trata el uint8_t
como un char
( uint8_t
suele ser solo un alias para unsigned 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 .
cout
está tratando aa
como char
de ASCII valor 5
que es un carácter no imprimible, intente encasillar a int
antes de imprimir.
uint8_t
probablemente será un typedef
para unsigned char
. La clase ostream
tiene una sobrecarga especial para unsigned char
, es decir, imprime el carácter con el número 5, que no es imprimible, de ahí el espacio vacío.
Haciendo uso de ADL (búsqueda de nombre dependiente del argumento):
#include <cstdint> #include <iostream> #include <typeinfo> namespace numerical_chars { inline std::ostream &operator<<(std::ostream &os, char c) { return std::is_signed<char>::value ? os << static_cast<int>(c) : os << static_cast<unsigned int>(c); } inline std::ostream &operator<<(std::ostream &os, signed char c) { return os << static_cast<int>(c); } inline std::ostream &operator<<(std::ostream &os, unsigned char c) { return os << static_cast<unsigned int>(c); } } int main() { using namespace std; uint8_t i = 42; { cout << i << endl; } { using namespace numerical_chars; cout << i << endl; } }
salida:
* 42
Un manipulador de flujo personalizado también sería posible.
- El operador unario plus también es una expresión clara (
cout << +i << endl
).