C++ 11 int8_t глючный ввод / вывод
Это фрагмент кода из моей программы. Я использую int8_t
тип данных, и у меня возникли некоторые проблемы с вводом / выводом. Видимо, используя int8_t
в программе требуется -std=c++11
флаг, который будет установлен для g++
компилятор. Я сделал это, но есть ошибки во время выполнения. Вот мой код:
#include <iostream>
#include <cstdint>
using std::cout;
using std::cin;
using std::endl;
int main() {
int8_t number;
cout << "Enter a number [1-100]: ";
cin >> number;
cout << "You entered: " << number << endl;
cout << number << " / 10 = " << (number / 10) << endl;
return 0;
}
Вот вывод программы:
$ ./a.out
Enter a number [1-100]: 95
You entered: 9
9 / 10 = 5
$
это приглашение оболочки В любом случае, кажется, что только первая цифра читается из входного потока. Несмотря на это, целочисленное деление 9 / 10
должен вернуться 0
не 5
, Эта программа предназначена для 95 / 10
и вернуть результат 9
, Теоретически эта программа должна работать, но, видимо, даже оператор деления глючит. Я должен отметить, что с помощью int
вместо int8_t
заставляет программу работать как задумано. Я подозреваю, что в этом случае кто-то просто скажет мне использовать int
Тип данных и справиться с этим. Но мы разработчики программного обеспечения! Я хотел бы знать, если int8_t
Тип данных по своей природе несовершенен. Почему он не может принять правильный ввод пользователя, но также нарушает оператор деления?! Любой язык программирования, который стоит использовать, не должен иметь таких недостатков. И я думаю, что C++ достаточно популярен, и в конце концов кто-то понял, что int8_t
в некотором смысле несовершенен. Это то, что мне нужно знать о тонкостях.
2 ответа
Во-первых, самый маленький тип в C++ char
и в большинстве систем последние пару десятилетий это равно 8-битному байту. Так типа int8_t
обычно псевдоним для signed char
,
Во-вторых, при чтении char
(signed
или же unsigned
) из потока с >>
оператор, он читает символ. Неважно, если псевдоним типа (например, int8_t
) используется, это все еще char
введите и будет читаться как символ.
Таким образом, в результате вы читаете один символ, и закодированное значение этого символа сохраняется в вашей переменной number
, С кодировкой ASCII (самая распространенная кодировка символов в наши дни) переменная number
будет хранить целочисленное значение 57
(ASCII для персонажа '9'
) который делится на 10
равно целому числу 5
,
Если вы хотите прочитать маленькое целое число, используйте int
для типа. Если вы хотите сохранить его в байте (используя int8_t
) вы должны либо использовать временный int
переменные, или приведите переменную к int
, Это литье должно быть сделано для печати (так как в противном случае char
перегрузка <<
оператор будет использоваться), поэтому я рекомендую использовать обычный int
типы для любых целых чисел по умолчанию.
Использование меньших типов, чем int
имеет значение только в том случае, если вы читаете / записываете необработанные двоичные данные или используете очень маленькую встроенную систему, в которой учитывается каждый байт (или, возможно, даже бит).
Размышляя о посте программиста, я бы хотел добавить свои впечатления. Кажется, так как int8_t
это псевдоним char
, cout
а также cin
автоматически обрабатывать переменную как char
и сделать ввод / вывод символов. Я нашел способ обойти это, и фактически сделать целочисленный пользовательский ввод / вывод для переменной. Это просто. Я использую функции языка программирования C printf()
а также scanf()
сделать работу. Эти функции имеют спецификаторы формата, которые позволяют обрабатывать переменные как данные любого типа. В то время как cout
а также cin
автоматически интерпретировать тип данных, вы можете сделать это вручную для printf()
а также scanf()
и это дает вам определенную степень силы. Теперь мой код выглядит так:
#include <iostream>
#include <cstdint>
#include <cstdio> // you need this for printf() and scanf()
using std::cout;
using std::cin;
using std::endl;
int main() {
int8_t number;
cout << "Enter a number [1-100]: ";
// %hhd allows you to treat int8_t as an integer data type, instead of
// a character
scanf("%hhd", &number);
printf("You entered: %hhd\n", number);
printf("%hhd / 10 = %hhd\n", number, (number / 10));
return 0;
}
И фактический вывод выглядит так:
$ ./a.out
Enter a number [1-100]: 95
You entered: 95
95 / 10 = 9
Это взлом, но это работает! Ну, вы узнаете что-то новое каждый день.
Редактируя этот ответ, я хотел бы добавить несколько релевантных ссылок на связанные вопросы для тех из вас, кто хочет провести дополнительное исследование.