0

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).

All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.

#include <iostream>
using namespace std;

void sort(int * a,int n)
{
    for(int i=0;i<n;++i)
        for(int j=i+1;j<n;++j)
        {
            if(a[i]>a[j])
            {
                int tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }\
        }
    return;
}

int main()
{
    int n;
    int check;
    int x;
    cout<<"Enter length of array:";
    cin>>n;
    if (n < 0){
        while (n < 0){
        cout << "Please enter a length greater than 0" << endl;
        cin >> n;
        }
    } else if (n % 1 != 0){
        while (n % 1 != 0){
            cout << "Whole numbers only! Try again" << endl;
            cin >> n;
        }
    }
    if (n == 0){
        cout <<"You try to enter numbers, but there's no place to put them." << endl;
        cout << ":(";
        return 0;
    }
    int a[n];
    cout<<"Enter values one by one:\n";
    for(int i=0;i<n;++i){
        cin >> x;
        a[i] = int(x);
    }
    sort(a,n);
    if (n % 2 == 1){
    cout<<"Median is:"<<a[n/2]<<endl;
    }
    else{
    float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
    cout << "Median is:" << z << endl;
    }




    return 0;
}

First thing I tried was catching the float like so

`if (n % 1 !=0){
    while(n % 1 !=0){
        cout << "Enter a whole number"
        cin >> n
    }
}`

This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.

I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.

I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.

How can I check against float user-input and loop them until they give me an int?

Podo
  • 709
  • 9
  • 30

1 Answers1

3

You're reading into an int:

int x;
...
cin >> x;

So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).

Instead, you could read into a float:

float x;
...
cin >> x;

And do the appropriate math.

Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.

And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.

Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

Community
  • 1
  • 1
Jason C
  • 38,729
  • 14
  • 126
  • 182
  • This is a fantastic idea (and one which I will be using in this situation), so you're saying it's impossible to read into an int with a float value? Or would the solution to circumvent that be long and pointless given this simple fix. – Podo Mar 30 '17 at 00:10
  • Oooh! Found a problem. The user can still enter a float value for the size of the array. That breaks the code :/ Any other thoughts? – Podo Mar 30 '17 at 00:12
  • @JeffreyDilley I think things would be less confusing if you stopped thinking along the lines of "inputting a float value". You aren't inputting a float. You're inputting a series of characters. Nothing is a float / int / etc. until it is parsed as such. So if you enter the series `3`, `.`, `1`, `4` but try parsing it as an `int`, you'll get the `3` because that's cool, then you'll hit the `.` and stop there because that's not cool, then the stream is stuck there. On the other hand if you try parsing it as a `float` it'll eat up the `.`, `1`, `4` just fine. – Jason C Mar 30 '17 at 00:13
  • @JeffreyDilley Sure. Read into a `float` when you ask for the size of the array and do whatever: round it to the nearest int, print an error if it's not an integer, etc. whatever you want. Or read into a `string` and then parse that `string` as an `int` in a separate step, that way no matter what the user inputs it'll always be consumed off the stream. – Jason C Mar 30 '17 at 00:15
  • I understand that completely. Makes perfect sense and you have done a fantastic job explaining. My issue though is not "Oh, I want to store a float but I'm only keeping the integer", it's "Oh crap, when a float is entered my code breaks". I would leave it as an int if it was content to take my entered value and truncate down to an int, but it doesn't. It just flops :/ – Podo Mar 30 '17 at 00:15
  • You're most recent comment looks like it might be the best solution! I'll give it a shot and hopefully all is well. Thanks! – Podo Mar 30 '17 at 00:16
  • @JeffreyDilley If you read into an `int` then you must accept the caveats that come with it, which is that it won't read things that aren't valid ints. So you either read into `float` and convert on your own, or read into `string` and parse on your own. There's also the option of doing error handling and skipping the rest of the input, I'll leave that to somebody else to answer, because I'm on my way out the door. – Jason C Mar 30 '17 at 00:17
  • 1
    @Jeffrey - You will still have to decide how much error checking you want. If you input into a `float`, I can enter `Hello!` and it will still break. – Bo Persson Mar 30 '17 at 00:21
  • @BoPersson , for the sake of ease I have decided that strings simply will not be entered, so that's not a problem in this case. If they were a possibility though, Jason's suggestion of reading to a string and then parsing the int from it would be a good fix I think :) – Podo Mar 30 '17 at 00:27