Проверка на целочисленность числа в С++

только начал изучать С++ и возник вопрос. Программа заполняет массив случайными числами, N - количество элементов массива. Необходимо проверить его на несколько параметров, проблема с проверкой введенного пользователем числа на целочисленность, проверка на тот случай, если пользователь введет с клавиатуры не целое число, например 2.2. Пытался несколькими способами -

if (typeid(N) != typeid(int)) 
 { 
  cout << "Количество элементов массива должно быть целым числом." << endl; 
  return 1; 
 
 }

или

switch(N)
    {
        case sizeof(N) != 4:
            cout << "введите целое число элементов массива";
        break;
    }

Однако корректно программа не работает, то переменные типа float не проходят проверку, то при вводе подходящего числа не составляется массив(например при вводе 2: вывод "Количество элементов массива должно быть целым числом), не могу найти проблему, помогите пожалуйста.

весь код:

#include <iostream> 
#include <stdlib.h> 
#include <ctime> 
#include <typeinfo> 
 
using namespace std; 
int main() 
{ 
 setlocale(LC_ALL, "Rus"); // для корректного вывода русского языка 
 long N; // количество элементов массива 
 float* pt; // используется для доступа к элементам массива A по адресу, а не по индексу 
 srand(time(NULL)); 
 
 cout << "введите четное количество символов "; 
 
 cin >> N; // ввод числа 
 

 
 
 if (typeid(N) != typeid(int)) 
 { 
  cout << "Количество элементов массива должно быть целым числом." << endl; 
  return 1; 
 
 } 
  
 else if (N == 0) 
 { 
  cout << "количество элементов массива не может быть равно нулю \n "; 
  return 1; 
   
 } 
 else if (N < 0) 
 { 
  cout << "количество элементов массива не может быть отрицательным \n "; 
  return 1; 
   
 } 
  
 else if (N % 2 != 0) 
 { 
  cout << "количество элементов массива должно быть четным \n "; 
  return 1; 
   
 } 
 
 float* A = new float[N]; //  оператор new для динамического выделения памяти под массив элементов типа float 
  
 
 cout << "первоначальный массив \n"; 
 
 for (int i = 0; i < N; i++) 
 { 
   
  A[i] = (float)rand() / RAND_MAX; // заполнение массива случайными числами 
  cout <<  *(A + i) << endl; // вывод массива 
 } 
 
 pt = A; // присваивает указателю pt адрес начала массива A 
 
 for (int i = 0; i < N; i+=2) // цикл с шагом 2, для того, чтобы поменять местами каждую пару в массиве 
 { 
  float perv = *(pt + i); // временная переменная, в которую сохраняется значение первого элемента массива из пары 
  *(pt + i) = *(pt + i + 1); // первому элементу из двойки присваивается следующий элемент(меняет местами) 
  *(pt + i + 1) = perv; // присваиваем второму элементу из двойки значение первого 
 } 
 cout << "массив с условием \n"; 
 
 for (int i = 0; i < N; i++) 
 { 
  cout << *(pt + i) << endl; // вывод массива с условием 
 } 
}

Ответы (2 шт):

Автор решения: user7860670

Рассматриваем случай, когда число считывается из консоли по нажатию Enter. В cin >> N; перегруженный оператор >> сначала пропускает пробельные символы (при наличии), затем пытается читать цифры целого числа, пока не случится переполнение, либо пока он не наткнется на символ, отличный от цифры.

Если после пробельных символов поток встретит не цифру, а что-то другое (ввод G), и в случае переполнения (ввод 23333333333333333333333) чтение останавливается и у потока будет выставлен флаг состояния fail. Отсутствие этого флага следует сразу проверить явным вызовом функции if (not cin.fail()), либо if (cin.good()), либо через оператор приведения к bool if (cin) (что является более лаконичным эквивалентом вызова good).

Если после чтения нескольких цифр поток наткнется на первый не числовой символ (ввод 1.3), то чтение останавливается и никакой ошибки не возникает. Для проверки отсутствия остановки из-за встретившегося мусора следует достать из потока один символ - если это символ окончания строки, то все ОК.

В случае неуспешного чтения следует сбросить флаги состояния и пропустить оставшийся кусок строки. И не забыть проверить достижение конца потока (особенно полезно при перенаправлении стандартного ввода из файла).

#include <limits>
#include <iostream>
#include <cstdlib>

int inint()
{
    int result{};
    for (;;)
    {
        ::std::cout << "Input integer: " << ::std::flush;
        if ((::std::cin >> result) and ('\n' == ::std::cin.get()))
        {
            break;
        }
        // сброс состояния ошибок потока
        ::std::cin.clear();
        // пропуск мусора до символа переноса строки (включительно)
        ::std::cin.ignore(::std::numeric_limits<::std::streamsize>::max(), '\n');
        // проверка достижения конца потока
        if (::std::cin.eof())
        {
            ::std::cout << "End of input." << ::std::endl;
            ::std::exit(1);
        }
        ::std::cout << "Bad input, repeat." << ::std::endl;
    }
    return result;
}

int main()
{
    auto const x{inint()};
    ::std::cout << "got " << x << ::std::endl;
    auto const x2{inint()};
    std::cout << "got " << x2 << ::std::endl;
    auto const x3{inint()};
    ::std::cout << "got " << x3 << ::std::endl;
}

online compiler

Обратите внимание: на конце последней строки нет символа переноса строки.

G
23333333333333333333333
1.3
1
2
3

Input integer: Bad input, repeat.
Input integer: Bad input, repeat.
Input integer: Bad input, repeat.
Input integer: got 1
Input integer: got 2
Input integer: End of input.

→ Ссылка
Автор решения: Nikolai Vorobiev

Вот так: Берём строку и сравниваем её с таблицей символов ACSII(У вас русская локаль, так что там возможно будет немного иначе)


#include <iostream>
#include <string>
int main ()
{
{
    int a = 0;
    std::string b = {};
  try{
      std::cin >> b;
      for(char c: b){
          if(not((int(c) > 46 && int(c) < 58))){
            std::cout << "error";
            return 1;
          }
          else{
              a = std::stoi(b);
          }
      }
  }
  catch(...){
      std::cout << "error";
  }
  std::cout << "Hello, " << a << "!\n";
}
→ Ссылка