Как вывести беззнаковый / подписанный символ или <cstdint>типы как целые числа с << в C ++ - PullRequest
2 голосов
/ 29 октября 2010

Справочная информация:

У меня есть операторы потоков шаблонов (например, operator << (ostream &, std::vector <T>)) (которые выводят элементы контейнера, которые могут иметь некоторый 8-битный целочисленный тип (например, unsigned char, int_least8_t и т. Д.)cetera).

Проблема:

По умолчанию эти типы выводятся как 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 по-прежнему получает вывод какa char.

Тот же базовый тип (т. е. unsigned/signed char не может использоваться при перегрузках, поэтому я не могу определить перегрузку, например, operator << (ostream &, int_fast8_t).

Ответы [ 5 ]

3 голосов
/ 29 октября 2010

Вы путаете фактические данные, хранящиеся в переменной, с любым представлением, выбранным для печати. ​​

Подумайте об этом так: chars, ints, doubles, longs, в любом случае, это всего лишь куски памяти, в которых вы можете хранить числа. Символ - это число от 0 до 255 (или от -128 до 127) - вы можете представить его как символ ASCII или какчисло или звездочки на небе с помощью OpenGL.

Если вы хотите увидеть число, стоящее за символом «а», просто дайте указание вашей программе обработать этот кусок памяти (который для вас содержит«а») как число.Используйте броски.Здесь:

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

Посмотрите, поможет ли это!

2 голосов
/ 29 октября 2010

Один из способов, который приходит на ум, - это использовать черты типа для определения типа вывода для каждого типа. Вы должны были бы объявить это для каждого типа вручную. Черты могут быть определены как структура шаблона, которая специализируется для каждого типа данных, у которого тип вывода отличается от самого типа данных:

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;
}
1 голос
/ 29 октября 2010

Вы можете просто разыграть его:

#include<iostream>

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

65

1 голос
/ 29 октября 2010

Если я вас правильно понял ... выведите его так:

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, сохраненное в b.a и b абсолютно одинаковы.

0 голосов
/ 29 октября 2010

Вы можете разыграть их, прежде чем вывести их:

std::cout << (unsigned int) container[index];
...