Как вывести беззнаковый / подписанный тип char или <cstdint> в виде целых чисел с << в C++
Фон:
У меня есть операторы потока шаблонов (например, operator << (ostream &, std::vector <T>)
) (что выводит контейнерные элементы, которые могут иметь некоторый 8-битный целочисленный тип (например, unsigned char
, int_least8_t
и так далее).
Проблема:
По умолчанию эти типы выводятся как char
(ASCII). Я только использовал char
(или же wchar_t
или что угодно) для переменных ASCII, никогда не подписанные / подписанные типы. Как я могу получить эти другие 8-битные типы, чтобы всегда выводиться как signed int
/ unsigned int
(цифры) вместо этого, даже если вызывающий не знает тип?
Первые попытки:
Я пытался (с GCC), например, определение operator << (ostream &, unsigned char)
с броском в нем (то есть stream << static_cast <int> (value)
, Это работает для unsigned char
значения, но потом uint8_t
по-прежнему получает вывод в виде char
,
Тот же базовый тип (т.е. unsigned/signed char
не может использоваться при перегрузках, поэтому я не могу определить перегрузку, например operator << (ostream &, int_fast8_t)
,
5 ответов
Один из способов, который приходит на ум, - это использование признаков типа для определения типа вывода для каждого типа. Вы должны были бы объявить это для каждого типа вручную. Черты могут быть определены как шаблонная структура, которая специализируется для каждого типа данных, у которого тип вывода отличается от самого типа данных:
template< T >
struct output_trait {
typedef const T & output_type;
}
В своем операторе вы пишете:
std::cout << static_cast< output_trait< T >::output_type >( variable ) << std::endl;
Это не будет делать приведение по умолчанию, но для типов, для которых output_trait
специализируется он будет делать приведение:
template<>
struct output_trait< unsigned char > {
typedef unsigned int output_type;
}
Вы путаете фактические данные, хранящиеся в переменной, с любым представлением, выбранным для печати.
Думайте об этом так: chars
, ints
, doubles
, longs
В любом случае, это всего лишь куски памяти, в которых вы можете хранить числа. Символ - это число от 0 до 255 (или от -128 до 127) - вы можете выбрать его для представления в виде символа ASCII или как число, или как звезды на небе с помощью OpenGL.
Если вы хотите увидеть число, стоящее за символом "а", просто дайте указание вашей программе обрабатывать этот кусок памяти (который для вас содержит "а") как число. Используйте броски. Вот:
http://www.cplusplus.com/doc/tutorial/typecasting/
Посмотрите, поможет ли это!
Если я вас правильно понял.. выведите это так:
std::cout << ( unsigned int )char << '\n';
Или стиль C++ - используйте static_cast, например:
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;
}
и то и другое std::cout
напечатает то же самое: первый - код ASCII 'a'
: 97
второй - просто значение 97
, хранится в б. И то и другое, a
а также b
, абсолютно одинаковы.
Вы можете просто разыграть это:
#include<iostream>
int main()
{
uint8_t blah = 65;
std::cout << static_cast<int>(blah) << "\n";
return 0;
}
65
Вы можете разыграть их, прежде чем вывести их:
std::cout << (unsigned int) container[index];