-2

I learnt C++ programming since 3 months ago and currently met some problem.

This is the expected output that I was being assigned to expect the output: enter image description here

While the formula for the Harmonic mean and Geometric mean are: H is harmonic mean while G is geometric mean

H is harmonic mean while G is geometric mean.

I tried few ways using while-loop or do-while-loop together with the if-else statement to achieve the expecting output but whenever i purposely input the wrong such as letter s, negative number or decimal number, the program is directed me straight to the end of the program, without asking to retype or further input for next operation...

here is my latest code i made:

#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
int main()
{
double H, G, n, f, x;
long double HX = 0, GX = 1;
double TypeIn[1000] = {};


cout << "How many values to type?: ";
cin >> n;

while (!(n > 0) && (n == static_cast <int> (n)) && !(cin >> n));
{
    if (n != static_cast <int> (n))
    {
        cout << "No decimal number please: ";
        cin >> n;
    }

    else if (!(cin >> n))
    {
        cin.clear();
        cin.ignore();
        cout << "INTEGER number ONLY: ";
        cin >> n;
    }

    else if (n <= 0)
    {
        cout << "the number must be integer number more than 0, please retype: ";
        cin >> n;
    }
}


for (int k = 0; k < n; k++)
{
    cout << "Enter number #" << k + 1 << ": ";
    cin >> x;

    while (!(x > 0) && (x == static_cast <int> (x)) && !(cin >> x));
    {
        if (x != static_cast <int> (x))
        {
            cout << "No decimal number please: ";
            cin >> x;
        }

        else if (!(cin >> x))
        {
            cin.clear();
            cin.ignore();
            cout << "INTEGER number ONLY: ";
            cin >> x;
        }

        else if (x <= 0)
        {
            cout << "the number must be integer number more than 0, please retype: ";
            cin >> x;
        }
    }
        TypeIn[k] = x;

    HX += 1 / TypeIn[k];
    GX *= TypeIn[k];
}

H = n / HX;
f = 1 / n;
G = pow(GX, f);

cout << "\nFor data:";
for (int k = 0; k < n; k++)
{
    cout << TypeIn[k];
}
cout << setprecision(5);
cout << "\n\nThe harmonic mean is " << H << endl;
cout << "The geometric mean is " << G << endl;

system("pause");
return 0;
}

Help and change is much appreciated here.

warunapww
  • 966
  • 4
  • 18
  • 38
  • 1
    Why don't you take the input as a string and just confirm that all chars in the string are numbers (meaning that it is a positive number)? As long as you check that '0' is not the only char, you can simplify your code alot and just convert to int after. – Shawn Aug 16 '16 at 15:10
  • urm, the checking that is expected is like: if input is any alphabet, it will shows error of 'only integer number'; if input is negative number or zero, it will show error of 'number must be integer above 0'; and if input is with decimal places such as 5.6 or 4.00, it will show error of 'no decimal place, only integer'....... the thing only proceed if it is a positive integer.... – AetheneLockhart Aug 16 '16 at 15:28
  • Off topic: `cin.ignore();` is not sufficient to clean up after a user input error. It only ignores one character and the erroneous input could be much more than that. `cin.ignore(numeric_limits::max(), '\n');` should cover that by ignoring up until the user presses enter (or the user types long enough to overflow the input stream) – user4581301 Aug 16 '16 at 16:21

1 Answers1

0

You can just do the following with a string:

string line;
int yourNumber;

getline(cin, s);

//Cycle through the word and check for characters such as '@' which don't fit any of the specific error messages.
for (int i = 0; i < line.length(); i++){
    if (line[i] != '-' || line[i] != '.' || !(line[i] >= '0' && line[i] <= '9'){
        cout << "Generally invalid input such as 5sda2" << endl;
        break;
    }
}

//This line just checks if '-' exists in the string.
if (line.find('-') != std::string::npos)
    cout << "No negatives" << endl;
else if (line.find('.') != std::string::npos)
    cout << "No decimals" << endl;
else
    yourNumber = std::stoi(line);

The std::stoi function converts from a std::string to an integer. It is defined in the

#include <string> header

which you need anyways for std::string. If you use cin before using getline, make sure to call cin.ignore in order to get over the whitespace left in the buffer (When and why do I need to use cin.ignore() in C++?).

Community
  • 1
  • 1
Shawn
  • 409
  • 3
  • 12
  • I think the edits of myself and some other editor collided and may have broken the question. I have reverted to let this other have another kick at the can. But, please fix the broken " #include header" header to "`#include ` header" – user4581301 Aug 16 '16 at 16:18
  • My bad, that started life as pseudocode so had no headers. Added and – Shawn Aug 16 '16 at 16:24
  • Actually the problem is in the text below the code block. Without code tagging the `` of `#include ` gets seen as an unsupported XML tag and is discarded. – user4581301 Aug 16 '16 at 16:28
  • i see... the pseudocode is far more better....... oh yea, i forgot to ask and mentioned as well, from my program there u should notice all those if-else statement having those output message and then the cin's, because the expected program is that, any error message popped out, i will have to retype in the number, if error found once more, it will need me to retype again and again until no error, then only proceed to next operations................ so, is it okay if i act the same way to the your replied pseudocode here? – AetheneLockhart Aug 16 '16 at 16:46
  • Ah I see, never knew that about the xml tagging. Thanks. And @AetheneLockhart : Yeah a simple way to keep getting the input is to create a bool that starts as true (lets say bool redoInput = true) and put that entire block in a while loop of the form while(redoInput). At the end if the input is good (where I called stoi) you can also just change redoInput to false, and then it will exit the loop. Make sure to use brackets to if you have more than one line under an if / else block.. – Shawn Aug 16 '16 at 17:01
  • i tried to execute the program that @ShawnS suggested and it seems to have C2661 error that saying no overload functions take 1 argument, whick red-lined 'cin.getline(line)' in my code what i know is that this 'cin.getline' are mostly use when earlier declared with char type onlu usable. In this case i have my early declaration of 'string line;', what to do if i have to need to solve this error? – AetheneLockhart Aug 17 '16 at 03:45
  • Why are you using cin.getline? If you have basic questions like this google things like the following: http://www.cplusplus.com/reference/string/string/getline/. The correct format as shown in the link is std::getline (std::cin, line); where line is whatever string you're using to store the input. – Shawn Aug 17 '16 at 15:23
  • Many thanks to the suggestions from you guys :D It works pretty flawless :D – AetheneLockhart Aug 17 '16 at 16:09
  • Np, if it worked for you feel free to accept it as the correct answer – Shawn Aug 17 '16 at 17:27