Eu tenho um problema estranho sobre como trabalhar com números inteiros em C ++.
Eu escrevi um programa simples que define um valor para uma variável e depois o imprime, mas não está funcionando conforme o esperado.
Meu programa tem apenas duas linhas de código:
uint8_t aa = 5;
cout << "value is " << aa << endl;
A saída deste programa é value is
Ou seja, ele imprime em branco para aa
.
Quando mudo uint8_t
para uint16_t
o código acima, funciona como um encanto.
Eu uso o Ubuntu 12.04 (Precise Pangolin), 64 bits, e minha versão do compilador é:
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Respostas:
Realmente não imprime um espaço em branco, mas provavelmente o caractere ASCII com o valor 5, que não é imprimível (ou invisível). Há vários códigos de caracteres ASCII invisíveis , a maioria deles abaixo do valor 32, que é o espaço em branco.
Você precisa converter
aa
paraunsigned int
para gerar o valor numérico, poisostream& operator<<(ostream&, unsigned char)
tenta gerar o valor do caractere visível.fonte
int
. Um elenco é uma maneira de fazer isso, mas não a única.+aa
também funciona.int(var)
e(int)var
tem exatamente o mesmo significado.int(var)
é desencorajado exatamente nos casos em que(int)var
é, exatamente pelas mesmas razões, porque significa exatamente a mesma coisa. (Eu posso entender por que você iria para ele aqui de qualquer maneira, embora, então eu não estou dizendo que você precisa para usostatic_cast
Eu só acho que a trilha comentário aqui tem um pouco desnecessariamente confuso..)uint8_t
provavelmente será umtypedef
paraunsigned char
. Aostream
classe possui uma sobrecarga especial paraunsigned char
, ou seja, imprime o caractere com o número 5, que não é imprimível, daí o espaço vazio.fonte
A adição de um operador + unário antes da variável de qualquer tipo de dados primitivo fornecerá valor numérico imprimível em vez de caractere ASCII (no caso do tipo char).
fonte
uint8_t
comounsigned char
valores numéricos?uint8_t
seja apenas um tipo de definiçãounsigned char
,unsigned char
ele é tratadoostream
exatamente comochar
e imprime seu valor ASCII.unsigned char
que explica muito. Então, o único número inteiro éint
, certo?short int
que ocupa 2 bytes. Existem algumas outras variações do tipo inteiro também.long
ouint
porque o compilador otimizaria o uso de RAM ou flash de acordo com o que preenche esse registro, estou certo?Isso ocorre porque o operador de saída trata
uint8_t
como achar
(uint8_t
geralmente é apenas um alias paraunsigned char
), por isso imprime o caractere com o código ASCII (que é o sistema de codificação de caracteres mais comum)5
.Veja, por exemplo, esta referência .
fonte
signed
e doisunsigned
(além da planície,char
que em C ++ é realmente um terceiro tipo separado). Então, seuint8_t
é um alias paraunsigned char
(muito provável), é isso que será usado.Fazendo uso da ADL (pesquisa de nome dependente de argumento):
resultado:
Um manipulador de fluxo personalizado também seria possível.
cout << +i << endl
).fonte
return std::is_signed<char>::value ? os << static_cast<int>(c) : os << static_cast<unsigned int>(c);
cout
está tratandoaa
com ochar
valor ASCII,5
que é um caractere não imprimível, tente converter paraint
antes da impressão.fonte
A
operator<<()
sobrecarga entreistream
echar
é uma função não membro. Você pode usar explicitamente a função de membro para tratar umchar
(ou auint8_t
) como umint
.Resultado:
fonte
Como outros disseram antes, o problema ocorre porque o fluxo padrão trata char assinado e char não assinado como caracteres únicos e não como números.
Aqui está minha solução com alterações mínimas de código:
A adição
"+0"
é segura com qualquer número, incluindo ponto flutuante.Para tipos inteiros, o tipo de resultado será alterado para
int
ifsizeof(aa) < sizeof(int)
. E isso não mudará de tipo sesizeof(aa) >= sizeof(int)
.Essa solução também é boa para preparar
int8_t
a impressão para transmitir, enquanto outras soluções não são tão boas:Resultado:
A solução PS com ADL dada por pepper_chico e πάντα ῥεῖ é realmente bonita.
fonte