Como gerar tipos de caracteres não assinados/assinados ou <cstdint> como números inteiros com << em C++

StackOverflow https://stackoverflow.com/questions/4049986

Pergunta

Fundo:

Eu tenho operadores de fluxo de modelo (por exemplo operator << (ostream &, std::vector <T>)) (que gera elementos do contêiner que podem ser de algum tipo inteiro de 8 bits, (por exemplo, unsigned char, int_least8_t, etc.).

Problema:

O padrão é que esses tipos sejam gerados como char (ASCII).eu só usei char (ou wchar_t ou qualquer outra coisa) para variáveis ​​ASCII, nunca tipos não assinados/assinados.Como faço para que esses outros tipos de 8 bits sejam sempre exibidos como signed int / unsigned int (números), mesmo quando o chamador não sabe o tipo?

Primeiras tentativas:

Eu tentei (com GCC), por exemplo, definir operator << (ostream &, unsigned char) com um elenco nele (ou seja, stream << static_cast <int> (value).Isso funciona para unsigned char valores, mas então uint8_t ainda obtém saída como um char.

O mesmo tipo subjacente (ou seja, unsigned/signed char não pode ser usado em sobrecargas, então não posso definir uma sobrecarga de, por exemplo operator << (ostream &, int_fast8_t).

Foi útil?

Solução

Uma maneira que vem à mente é usar características de tipo para definir o tipo de saída para cada tipo.Você teria que declarar isso para cada tipo manualmente.As características podem ser definidas como uma estrutura de modelo especializada para cada tipo de dados que possui um tipo de saída diferente do próprio tipo de dados:

template< T >
struct output_trait {
    typedef const T & output_type;
}

Na sua operadora você escreve:

std::cout << static_cast< output_trait< T >::output_type >( variable ) << std::endl;

Isso não fará conversão por padrão, mas para tipos para os quais output_trait é especializado fará um elenco:

template<>
struct output_trait< unsigned char > {
    typedef unsigned int output_type;
}

Outras dicas

Você está confundindo os dados reais mantidos em uma variável com qualquer representação escolhida para imprimi-la.

Pense desta forma: chars, ints, doubles, longs, tanto faz, eles são apenas pedaços de memória para você armazenar números.Um caractere é um número entre 0 e 255 (ou -128 e 127) – você pode optar por representá-lo como um caractere ASCII, ou como um número, ou como estrelas no céu com a ajuda do OpenGL.

Se você quiser ver o número atrás do caractere 'a', apenas instrua seu programa a tratar aquele pedaço de memória (que contém um 'a') como um número.Use moldes.Aqui:

http://www.cplusplus.com/doc/tutorial/typecasting/

Veja se isso ajuda!

Você pode simplesmente lançá-lo:

#include<iostream>

int main()
{
 uint8_t blah = 65;
 std::cout << static_cast<int>(blah) << "\n";
 return 0;
}

65

Se eu entendi direito..produza assim:

std::cout << ( unsigned int )char << '\n';

Ou mais estilo c++ - use static_cast, por exemplo:

int main()
{
    char a = 'a';
    char b = 97;
    std::cout << static_cast< unsigned int >( a ) << '\n';
    std::cout << static_cast< unsigned int >( b ) << '\n';
    return 0;
}

ambos std::cout imprimirá o mesmo:o primeiro - o código ASCII de 'a': 97, o segundo - apenas o valor 97, armazenado em b.Ambos, a e b, são absolutamente iguais.

Você pode lançá-los antes de produzi-los:

std::cout << (unsigned int) container[index];
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top