0

My target is to validate input value before add it into array. Current code used:

int main()
{
    int temp;
    int arr[5];
    for(int i = 0; i < 5; i++)
    {
        // validate here
        cin >> arr[i];
    }
    return 0;
}

and my validation method:

int validateInput(string prompt)
{
    int val;
    while (true)
    {
        cin.clear();
        cin.sync();
        cout << prompt;
        cin >> val;
        if (cin.good() && val >= -50 && val <= 50)
        {
            break;
        }
        else
            cin.clear();
        cout << "Invalid input! number must be between -50 and 50" << endl;
    }
    return val;
}

How is that possible?

4
  • 3
    How is what possible? Commented Mar 22, 2017 at 15:13
  • You have a function that reads some input and "validates" it, what is the problem with it? Commented Mar 22, 2017 at 15:14
  • 1
    With C++, you could build something that enables you to write cin >> Foo(arr[i], -50, 50). Google "overloading istream >>". Alas, the boring simple way is probably more practical. Commented Mar 22, 2017 at 15:16
  • Prefer to use std::vector. Arrays have the possibility of buffer overflow, and are difficult to pass to functions (compared to vectors). Commented Mar 22, 2017 at 15:31

3 Answers 3

2

Your validateInput should just deal with validation: it should answer "is x valid or not valid?"

bool validateInput(int x)
{
    return val >= -50 && val <= 50;
}

When reading from stdin, use validateInput and branch accordingly:

for(int i = 0; i < 5; i++)
{
    int temp;
    cin >> temp;

    if(cin.good() && validateInput(temp))
    {
        arr[i] = temp;
    }
    else
    {
        cout << "Invalid input! number must be between -50 and 50" << endl;
        // handle invalid input
    }
}

If you want to further abstract the idea of "only reading valid numbers from std::cin", you can use an higher-order function:

template <typename TFValid, typename TFInvalid, typename TFInvalidIO>
decltype(auto) processInput(TFValid&& f_valid, TFInvalid&& f_invalid, TFInvalidIO&& f_invalid_io)
{
     int temp;
     cin >> temp;

     if(!cin.good()) 
     {
         // Invalid IO.
         return std::forward<TFInvalidIO>(f_invalid_io)();
     }

     if(validateInput(temp))
     {
         // Valid IO and datum.
         return std::forward<TFValid>(f_valid)(temp);
     }

     // Valid IO, but invalid datum.
     return std::forward<TFInvalid>(f_invalid)(temp);
}

Usage:

for(int i = 0; i < 5; i++)
{
    processInput([&](int x){ arr[i] = x; },
                 [](int x){ cout << x << " is invalid"; },
                 []{ cout << "Error reading from cin"; });
}

If you want more genericity you can also pass validateInput and the type of input as an additional parameters.

Sign up to request clarification or add additional context in comments.

6 Comments

You might want to add the cin >> temp as part of the condition in the if statement.
No no, I have validation method, which I want to combine in main
In your answer if input is not valid, it will not prompt again. In my method it prompts till valid
You most likely want cin.good() && validateInput(temp), i.e. && instead of logical bit-and &. For bool the only difference will be in that && does short-cicuit evaluation, but for non-bools, & is very different from &&.
@vsoftco: that was a typo :)
|
0

Vittorio's answer above is spot on. For completeness, if you want exactly 5 elements:

#include <string>
#include <iostream>

using namespace std;

bool validateInput(int inValue)
{
  return inValue >= -50 && inValue <= 50;
}

int main()
{
  int _arr[5];
  int _currentIdx = 0;
  int _tmp;
  while (_currentIdx < 5)
  {
    cin >> _tmp;
    if (validateInput(_tmp))
    {
      _arr[_currentIdx] = _tmp;
      _currentIdx++;
    }
    else
    {
      cout << "Invalid input! number must be between -50 and 50" << endl;
    }
  }
}

2 Comments

In your answer if input is not valid, it will not prompt again. In my method it prompts till valid
@TeodorKolev How so? If input is invalid _currentIdx is not increased and it will prompt again for the given array index.
0

replace

cin >> temp;

with

arr[i] = validateInput("some str");

1 Comment

There's no temp in the question. Are you sure this is an answer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.