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)

Ответ 1

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

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

uint8_t aa=5;

cout << "value is " << unsigned(aa) << endl;

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

См. эта ссылка.

Ответ 5

  • Использование ADL (поиск по зависимым от аргумента):

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

    выход:

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

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

Ответ 6

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

Ответ 7

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

#include <iostream>
#include <cstddef>

int main()
{
   uint8_t aa=5;

   std::cout << "value is ";
   std::cout.operator<<(aa);
   std::cout << std::endl;

   return 0;
}

Вывод:

value is 5

Ответ 8

Как сообщалось ранее, проблема возникает, потому что стандартный поток обрабатывает подписанные 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 для печати в потоке, в то время как некоторые другие решения не так хороши:

int8_t aa = -120;

cout << "value is " << aa + 0 << endl;
cout << "bad value is " << unsigned(aa) << endl;

Вывод:

value is -120
bad value is 4294967176

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