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

Это взлом, но это работает! Ну, вы узнаете что-то новое каждый день.


Редактируя этот ответ, я хотел бы добавить несколько релевантных ссылок на связанные вопросы для тех из вас, кто хочет провести дополнительное исследование.

Предназначены ли int8_t и uint8_t для типов символов?

Разница между int32, int, int32_t, int8 и int8_t

Другие вопросы по тегам