Comment sortie unsigned / signed char ou types comme des entiers avec << en C ++
-
27-09-2019 - |
Question
Arrière-plan:
Je opérateurs de flux de modèle (par exemple operator << (ostream &, std::vector <T>)
) (que les éléments conteneurs de sortie qui peut éventuellement être d'un type quelconque d'entiers de 8 bits, (par exemple unsigned char
, int_least8_t
, et cetera).
Problème:
Par défaut est que ces types sont sortis comme char
(ASCII).
Je ne char
(ou wchar_t
ou autre) pour les variables ASCII, jamais types non signés / signés.
Comment puis-je obtenir ces types 8 bits pour être toujours sortie comme signed int
/ unsigned int
(chiffres) à la place, même lorsque l'appelant ne connaît pas le type?
essaie d'abord:
J'ai essayé (avec GCC), par exemple la définition operator << (ostream &, unsigned char)
avec un casting en elle (à savoir stream << static_cast <int> (value)
. Qui fonctionne pour les valeurs de unsigned char
, mais uint8_t
obtient toujours sortie en char
.
Le même type sous-jacent (par exemple unsigned/signed char
ne peut pas être utilisé dans les surcharges, je ne peux pas définir une surcharge par exemple operator << (ostream &, int_fast8_t)
.
La solution
Une façon qui vient à l'esprit est d'utiliser des traits de type pour définir le type de sortie pour chaque type. Vous devrez déclarer que, pour chaque type à la main. Les traits peuvent être définis comme une structure de modèle qui est spécialisé pour chaque type de données qui a un autre type de sortie que les données de type elle-même:
template< T >
struct output_trait {
typedef const T & output_type;
}
Dans votre opérateur, vous écrivez:
std::cout << static_cast< output_trait< T >::output_type >( variable ) << std::endl;
Cela ne ne jetterai par défaut, mais pour les types pour lesquels output_trait
est spécialisée elle fera un casting:
template<>
struct output_trait< unsigned char > {
typedef unsigned int output_type;
}
Autres conseils
Vous confondez les données réelles détenues dans une variable, avec quelle que soit la représentation que vous choisissez pour l'imprimer.
Pensez-y de cette façon: chars
, ints
, doubles
, longs
, whatevers, ils sont tous juste des morceaux de mémoire pour vous numéros dans char est un nombre compris entre 0 et 255 (ou -128 et 127). -., vous pouvez choisir de le représenter comme un caractère ASCII, ou plusieurs, ou comme des étoiles dans le ciel à l'aide d'OpenGL
Si vous souhaitez voir le numéro derrière le personnage « a », juste demander à votre programme pour traiter ce morceau de mémoire (pour vous contient un « a ») comme un nombre. Utilisez jette. Ici:
http://www.cplusplus.com/doc/tutorial/typecasting/
voir si cela aide!
Vous pouvez simplement jeter:
#include<iostream>
int main()
{
uint8_t blah = 65;
std::cout << static_cast<int>(blah) << "\n";
return 0;
}
65
Si je comprends bien .. sortie comme ceci:
std::cout << ( unsigned int )char << '\n';
Ou plus c ++ de style - l'utilisation static_cast, par exemple:
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;
}
Les deux std::cout
imprimera le même: le premier - le code ASCII de 'a'
: 97
, le second - juste la valeur 97
, stockée dans b. Les deux, a
et b
, sont tout à fait la même chose.
Vous pouvez les jeter avant de les afficher:
std::cout << (unsigned int) container[index];