uint8_t не может быть напечатан cout

У меня есть странная проблема с работой с целыми числами на C ++.

Я написал простую программу, которая задает значение переменной и затем печатает ее, но она не работает должным образом.

Моя программа имеет только две строки кода:

uint8_t aa = 5; cout << "value is " << aa << endl; 

Выходом этой программы является value is

То есть, он печатает пробел для aa .

Когда я меняю uint8_t на uint16_t приведенный выше код работает как шарм.

Я использую Ubuntu 12.04 (Precise Pangolin), 64-битный, и моя версия компилятора:

 gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 

Он действительно не печатает пустой, но, скорее всего, символ ASCII со значением 5, который не печатается (или невидим). Существует ряд невидимых кодов символов ASCII , большинство из которых ниже значения 32, что фактически пусто.

Вам нужно преобразовать aa в unsigned int для вывода числового значения, так как ostream& operator<<(ostream&, unsigned char) пытается вывести видимое значение символа.

 uint8_t aa=5; cout << "value is " << unsigned(aa) << endl; 

uint8_t скорее всего будет typedef для unsigned char . Класс ostream имеет специальную перегрузку для unsigned char , т. ostream символ с номером 5, который не подлежит печати, а значит и пустым пространством.

Добавление унарного оператора + перед переменной любого примитивного типа данных даст печатное числовое значение вместо символа ASCII (в случае типа char).

 uint8_t aa=5; cout<<"value is "<< +aa < 
  • Использование ADL (зависящий от Argument поиск имени):

     #include  #include  #include  namespace numerical_chars { inline std::ostream &operator<<(std::ostream &os, char c) { return std::is_signed::value ? os << static_cast(c) : os << static_cast(c); } inline std::ostream &operator<<(std::ostream &os, signed char c) { return os << static_cast(c); } inline std::ostream &operator<<(std::ostream &os, unsigned char c) { return os << static_cast(c); } } int main() { using namespace std; uint8_t i = 42; { cout << i << endl; } { using namespace numerical_chars; cout << i << endl; } } 

    вывод:

     * 42 
  • Также возможен пользовательский манипулятор streamа.

  • Унарный плюс также является опрятным идиомом ( cout << +i << endl ).

Это потому, что оператор вывода рассматривает uint8_t как char ( uint8_t обычно является просто псевдонимом для unsigned char ), поэтому он печатает символ с кодом ASCII (который является наиболее распространенной системой кодирования символов) 5 .

См., Например, эту ссылку .

cout обрабатывает aa как char из значения ASCII 5 который является непечатаемым символом, перед печатью попробуйте ввести тип int .

Перегрузка operator<<() между istream и char является функцией, не являющейся членом. Вы можете явно использовать функцию-член для обработки char (или uint8_t ) как int .

 #include  #include  int main() { uint8_t aa=5; std::cout << "value is "; std::cout.operator<<(aa); std::cout << std::endl; return 0; } 

Вывод:

 value is 5 

Как говорили другие до возникновения проблемы, поскольку стандартный stream обрабатывает подписанный символ char и unsigned char как одиночные символы, а не как числа.

Вот мое решение с минимальными изменениями кода:

 uint8_t aa = 5; cout << "value is " << aa + 0 << endl; 

Добавление "+0" безопасно с любым числом, включая с плавающей запятой.

Для целых типов он изменит тип результата на int если sizeof(aa) < sizeof(int) . И это не изменит тип, если sizeof(aa) >= sizeof(int) .

Это решение также полезно для подготовки int8_t для печати в streamе, в то время как некоторые другие решения не так хороши:

 int8_t aa = -120; cout << "value is " << aa + 0 << endl; cout << "bad value is " << unsigned(aa) << endl; 

Вывод:

 value is -120 bad value is 4294967176 

PS Решение с ADL, данное pepper_chico и πάντα ῥεῖ, действительно красиво.

  • Чтение имен файлов из каталога
  • Как подключиться к GetWindowLongPtr и SetWindowLongPtr на 32-битных платформах?
  • Почему пример по умолчанию не изменяет входной параметр?
  • Log4Net, как добавить настраиваемое поле в мой журнал
  • Создание элементов из 3 коллекций с использованием Linq
  • Что значит для функции C ++ быть встроенным?
  • HttpWebRequest и проверка подлинности форм в C #
  • Расширение стандартной библиотеки C ++ по наследству?
  • Каков самый быстрый способ объединить два xml-файла в один
  • C - scanf () vs получает () vs fgets ()
  • Регистрация типа C ++ во время компиляции
  • Interesting Posts

    Каков самый простой способ получить подробный список оборудования в моей Windows-коробке?

    Как вы регистрируете DLL-файл Win32 COM в WiX 3?

    Изменение цвета строки состояния с помощью AppCompat ActionBarActivity

    Почему для нулевого указателя используется нулевой адрес?

    Почему плагины notepad ++ не работают в макросе?

    Можете ли вы удалить элементы из std :: list во время итерации через него?

    Есть ли ActivityIndicator в WatchKit для Apple Watch?

    Ярлык клавиатуры для отображения или снятия с экрана окна в OS X

    Экспорт classов, содержащих std :: objects (вектор, карта и т. Д.) Из dll

    Программно выберите элемент ListView в Android

    Можем ли мы подключить удаленную базу данных MySQL на Android с помощью JDBC?

    Получить общее количество шагов для каждой даты в HealthKit

    Существуют ли большие различия в скорости между различными жесткими дисками?

    Широкоэкранный набор приложений – Java Swing

    VIMRC, SCREENRC, BASHRC, KSHRC и т. Д. Что означает «RC»?

    Давайте будем гением компьютера.