тип 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)
8 ответов:
на самом деле он не печатает пустой, но, скорее всего, символ ASCII со значением 5, который не печатается (или невидим). Есть несколько невидимые коды символов ASCII, большинство из них ниже значения 32, которое на самом деле является пустым.
вы должны преобразовать
aatounsigned 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Как achar(uint8_tобычно это просто псевдоним дляunsigned char), поэтому он печатает символ с кодом ASCII (который является наиболее распространенной системой кодирования символов)5.см., например,этой ссылке.
coutлечениеaaкакcharзначения ASCII5который является непечатным символом, попробуйте ввести в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 4294967176P.S. решение с ADL, данное pepper_chico и πάντα ῥεῖ, действительно красиво.
Comments