тип uint8 T может не быть напечатаны с cout



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



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



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



uint8_t aa = 5;

cout << "value is " << aa << endl;


выход этой программы value is



т. е., он печатает пустой для aa.



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



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



gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
883   8  
c++

8 ответов:

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

вы должны преобразовать aa to 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, т. е. он печатает символ с номером 5, который не может быть напечатан, следовательно, пустое пространство.

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

uint8_t aa=5;
cout<<"value is "<< +aa <<endl;
  • использование 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).

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

см., например,этой ссылке.

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

The operator<<() перегрузка между istream и char является функцией, не являющейся членом. Вы можете явно использовать функцию-член для обработки char (или 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

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

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

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 и πάντα ῥεῖ, действительно красиво.

Comments

    Ничего не найдено.