У меня странная проблема с работой с целыми числами в C ++.
Я написал простую программу, которая устанавливает значение переменной и затем распечатывает его, но она не работает должным образом.
В моей программе всего две строчки кода:
uint8_t aa = 5;
cout << "value is " << aa << endl;
Результатом этой программы является value is
То есть для aa
.
Когда я перехожу uint8_t
на uint16_t
приведенный выше код, он работает как шарм.
Я использую 64-разрядную версию Ubuntu 12.04 (Precise Pangolin), и моя версия компилятора:
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;
источник
int
. Приведение - это один из способов сделать это, но не единственный.+aa
тоже работает.int(var)
и(int)var
имеете то же значение.int(var)
не рекомендуется в тех случаях, когда(int)var
есть, по точно таким же причинам, потому что это означает одно и то же. (Я могу понять, почему вы все равно пошли на это здесь, поэтому я не говорю, что вам нужно использоватьstatic_cast
. Я просто думаю, что след комментариев здесь немного излишне запутанный.)uint8_t
скорее всего будетtypedef
дляunsigned char
.ostream
Класс имеет специальную перегрузкуunsigned char
, т.е. печатает символ с номером 5, который является не для печати, следовательно , пустое пространство.источник
Добавление унарного оператора + перед переменной любого примитивного типа данных даст печатное числовое значение вместо символа ASCII (в случае типа char).
uint8_t aa = 5; cout<<"value is "<< +aa <<endl; // value is 5
источник
uint8_t
какunsigned char
числовые значения?uint8_t
это просто определение типаunsigned char
, оноunsigned char
само обрабатываетсяostream
аналогичноchar
и выводит его значение ASCII.unsigned char
которое многое объясняет. Итак, единственное целое числоint
, верно?short int
2 байта. Также есть несколько других вариантов целочисленного типа.long
илиint
потому что компилятор оптимизирует использование ОЗУ или флэш-памяти согласно тому, что заполняет этот регистр, я прав?Это потому, что оператор вывода обрабатывает
uint8_t
как achar
(uint8_t
обычно это просто псевдоним дляunsigned char
), поэтому он печатает символ с кодом ASCII (который является наиболее распространенной системой кодировки символов)5
.См., Например, эту ссылку .
источник
signed
и дляunsigned
символов (помимо простого,char
который в C ++ на самом деле является третьим отдельным типом). Так что еслиuint8_t
это псевдонимunsigned char
(очень вероятно), он и будет использоваться.Использование 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
).источник
return std::is_signed<char>::value ? os << static_cast<int>(c) : os << static_cast<unsigned int>(c);
cout
обрабатываетсяaa
какchar
значение ASCII,5
которое является непечатаемым символом, попробуйте привести типint
перед печатью.источник
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
источник
Как уже говорилось ранее, проблема возникает из-за того, что стандартный поток обрабатывает подписанные char и unsigned char как отдельные символы, а не как числа.
Вот мое решение с минимальными изменениями кода:
uint8_t aa = 5; cout << "value is " << aa + 0 << endl;
Добавление
"+0"
безопасно с любым числом , включая плавающую точку.Для целочисленных типов он изменит тип результата на
int
ifsizeof(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
PS Решение с ADL от pepper_chico и πάντα ῥεῖ действительно красивое.
источник