0

I have a simple code wherein i am finding simple interest and compound interest. The issue I am facing is that I have to use CLI for input. I need one int and two floats to work with. Earlier i was using cin.fail() which was doing the type checking for me and that worked perfectly but i need to take CLI such that inputs such as 1000 1? 5 are treated as invalid. Please help.

#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstdlib>

using namespace std;

int main(int argc, char *argv[])
{  
    int p;
    float r,t,ci;

    p=atoi(argv[1]);
    r=atof(argv[2]);
    t=atof(argv[3]);

    if(p<=0 || r==0 || t<=0) {
        //we want p>0 t>0 and r==0 from the logic that atof will retrun 0 if r is non numeric
        cout<<"Invalid Input"<<endl;
    }
    else {
        float si=(p*r*t)/100;
        cout<<"Simple interest:"<<fixed<<setprecision(2)<<si<<endl;
        ci=p*pow((1+r/100),t)-p;
        cout<<"Compound interest:"<<ci<<endl;
    }

    return 0;
}
  • What is preventing you from checking those conditions with a simple good old `if` condition? – Nicolas Louis Guillemot Aug 07 '14 at 11:08
  • i am not able to pinpoint the condition i should use! – user3918038 Aug 07 '14 at 11:10
  • @user3918038 You should reformulate the question, and possibly the title to make it clear what you are asking. Do you want a validation function for string-formatted floating point numbers? – Jonathan H Aug 07 '14 at 11:12
  • 1
    yes, this has nothing to do with real life application. I have to submit it for the class portal. – user3918038 Aug 07 '14 at 11:13
  • possible duplicate of [how to check if given c++ string or char\* contains only digits?](http://stackoverflow.com/questions/8888748/how-to-check-if-given-c-string-or-char-contains-only-digits) – Jonathan H Aug 07 '14 at 11:15
  • I don't understand how an opinionated comment that has nothing to do with the OP gets the most upvotes... – Jonathan H Aug 07 '14 at 11:23
  • @Sh3ljohn: Your suggested 'duplicate' is wrong, as the input here may contain a decimal point. – barak manos Aug 07 '14 at 11:33
  • @barakmanos And a minus sign too :) Oh my, such a difficult extension... The first solution literally lists the valid chars. – Jonathan H Aug 07 '14 at 11:35
  • `argv` is character array, so at first you need to determine where it ends. – ST3 Aug 07 '14 at 11:42

3 Answers3

0

Try adding this function to your code:

#include <ctype.h>

static bool isnumeric(char* theArgument, int maxdec)
{
    int decimalpoint = 0;
    while(*theArgument)
    {
        if (!isdigit(*theArgument))
        {
            if ('.' == *theArgument && maxdec <= ++decimalpoint)
            {
                continue;
            }
            return false;
        }
    }
    return true;
}

Call it for each of your arguments, with the maximum number of decimal points the argument can allow. In your case, that would be isnumeric(argv[1],0), isnumeric(argv[2],1), isnumeric(argv[3],1). That will tell you if your numbers are in fact formatted as nonnegative decimal numbers. A little more logic (not shown here) will also tell you if they have a minus sign.

Logicrat
  • 4,438
  • 16
  • 22
0

You can use strtol and strtod instead of atoi and atof:

long int p;
double r,t;

char* endptr1;
char* endptr2;
char* endptr3;

p = strtol(argv[1], &endptr1, 10);
r = strtod(argv[2], &endptr2);
t = strtod(argv[3], &endptr3);

if (*endptr1 != 0 || *endptr2 != 0 || *endptr3 != 0)
{
    cout<<"Invalid Input"<<endl;
}
else
{
    ...
}
barak manos
  • 29,648
  • 10
  • 62
  • 114
0

argv is character array, so it contains more characters.

Solution should be:

  1. Explode your argv into 3 parts, separator should be space (or multiple) symbol.
  2. Now cast it using strtol and strtod.
  3. Validate. strtol and strtod returns zero if no success, so in case you got zero, check if input was actualy '0'.
ST3
  • 8,826
  • 3
  • 68
  • 92