Hey guys, I have an integer validation problem.. i wanna validate integers for fractions where the numerator must be 0 <= num <= 20, and the denominator must be 1<= den <= 20.. and later on i want to multiply them together and simplify, but only the validation has a problem... the entire function is below:

``````void fractions()
{
int nullEnter = 0;
int numProd, denProd, numeratorLength, intCheck0, intCheck1, intCheck2, intCheck3, intCheck4, intCheck5, intCheck6;
int iNum1 = 0, iNum2 = 0, iDen1 = 0, iDen2 = 0, fracCheck = 0, invalid = 0, numIsZero = 0;
char frac1[7] = "", frac2[7] = "";
char tempNum1[4], tempNum2[4], tempNum3[4];
char numbers[11] = "0123456789";

printf("\nFractions\n--------------\n");
do
{	while(fracCheck == 0)           /*fraction 1 validation*/
{   printf("Enter fraction 1: ");
fgets(frac1, 7, stdin);
numeratorLength = strspn(frac1, numbers);      /*length of numerator*/

intCheck0 = atoi(&frac1[0]);
intCheck1 = atoi(&frac1[1]);
intCheck2 = atoi(&frac1[2]);
intCheck3 = atoi(&frac1[3]);
intCheck4 = atoi(strncpy(tempNum1, &frac1[0], 2));        /*converting XX into an integer in the fraction XX/y*/
intCheck5 = atoi(strncpy(tempNum2, &frac1[2], 2));        /*converting YY into an integer in the fraction x/YY*/
intCheck6 = atoi(strncpy(tempNum3, &frac1[3], 2));        /*converting YY into an integer in the fraction xx/YY*/

if(frac1[0] == '\n')
{   break;
}
else if(frac1[strlen(frac1)-1] != '\n')   /*length check*/
printf("Invalid fraction.\n\n");
invalid = 1;
}
else if((frac1[1] == '/') && (frac1[3] == '\n') && (intCheck0 != 0) && (intCheck2 != 0))
{   fracCheck = 1;   /*x/y check*/
iNum1 = atoi(&frac1[0]);
iDen1 = atoi(&frac1[2]);
}
else if((frac1[2] == '/') && (frac1[4] == '\n') && (intCheck4 != 0) && (intCheck3 != 0))
{   fracCheck = 1;   /*xx/y check*/
iNum1 = atoi(strncpy(tempNum2, &frac1[0], 2));
iDen1 = atoi(&frac1[3]);
}
else if((frac1[1] == '/') && (frac1[4] == '\n') && (intCheck0 != 0) && (intCheck5 != 0))
{   fracCheck = 1;   /*x/yy check*/
iNum1 = atoi(&frac1[0]);
iDen1 = atoi(strncpy(tempNum1, &frac1[2], 2));
}
else if((frac1[2] == '/') && (frac1[5] == '\n') && (intCheck4 != 0) && (intCheck6 != 0))
{   fracCheck = 1;   /*xx/yy check*/
iNum1 = atoi(strncpy(tempNum2, &frac1[0], 2));
iDen1 = atoi(strncpy(tempNum3, &frac1[3], 2));
}
else if((frac1[0] == '0') && (frac1[1] == '/') && (frac1[3] == '\n') && (intCheck2 != 0))
{   fracCheck = 1;   /*0/y check*/
numIsZero = 1;
iNum1 = 1;
iDen1 = 2;
}
else if((frac1[0] == '0') && (frac1[1] == '/') && (frac1[4] == '\n') && (intCheck5 != 0))
{   fracCheck = 1;   /*0/yy check*/
numIsZero = 1;
iNum1 = 1;
iDen1 = 2;
}
else
{   printf("Invalid fraction.\n\n");
invalid = 1;
}
/*up to this point the above ensures the fraction is in one of the 4 forms and they are integers*/

if((iNum1 > 20 || iDen1 == 0 || iDen1 > 20) && invalid == 0)
{   printf("Invalid fraction.  Allowed parameters- Numerator(0-20), Denominator(1-20)\n\n");
fracCheck = 0;
}

invalid = 0; /*re-initialize invalid*/
}   /*end of fraction 1 validation*/

if(frac1[0] == '\n')   /*check for a null enter*/
{   break;
}

while(fracCheck == 1)           /*fraction 2 validation and formatting*/
{   printf("Enter fraction 2: ");
fgets(frac2, 7, stdin);
numeratorLength = strspn(frac2, numbers);

intCheck0 = atoi(&frac2[0]);
intCheck1 = atoi(&frac2[1]);
intCheck2 = atoi(&frac2[2]);
intCheck3 = atoi(&frac2[3]);
intCheck4 = atoi(strncpy(tempNum1, &frac2[0], 2));        /*parsing the bracket(XX)/y*/
intCheck5 = atoi(strncpy(tempNum2, &frac2[2], 2));        /*parsing the bracket x/(YY)*/
intCheck6 = atoi(strncpy(tempNum3, &frac2[3], 2));        /*parsing the bracket xx/(YY)*/

if(frac2[0] == '\n')
{   break;
}
else if(frac2[strlen(frac2)-1] != '\n')   /*length check*/
printf("Invalid fraction.\n\n");
invalid = 1;
}
else if((frac2[1] == '/') && (frac2[3] == '\n') && (intCheck0 != 0) && (intCheck2 != 0))
{   fracCheck = 2;   /*x/y check*/
iNum2 = atoi(&frac2[0]);
iDen2 = atoi(&frac2[2]);
}
else if((frac2[2] == '/') && (frac2[4] == '\n') && (intCheck4 != 0) && (intCheck3 != 0))
{   fracCheck = 2;   /*xx/y check*/
iNum2 = atoi(strncpy(tempNum2, &frac2[0], 2));
iDen2 = atoi(&frac2[3]);
}
else if((frac2[1] == '/') && (frac2[4] == '\n') && (intCheck0 != 0) && (intCheck5 != 0))
{   fracCheck = 2;   /*x/yy check*/
iNum2 = atoi(&frac2[0]);
iDen2 = atoi(strncpy(tempNum1, &frac2[2], 2));
}
else if((frac2[2] == '/') && (frac2[5] == '\n') && (intCheck4 != 0) && (intCheck6 != 0))
{   fracCheck = 2;   /*xx/yy check*/
iNum2 = atoi(strncpy(tempNum2, &frac2[0], 2));
iDen2 = atoi(strncpy(tempNum3, &frac2[3], 2));
}
else if((frac2[0] == '0') && (frac2[1] == '/') && (frac2[3] == '\n') && (intCheck2 != 0))
{   fracCheck = 1;   /*0/y check*/
numIsZero = 1;
iNum2 = 1;
iDen2 = 2;
}
else if((frac2[0] == '0') && (frac2[1] == '/') && (frac2[4] == '\n') && (intCheck5 != 0))
{   fracCheck = 1;   /*0/yy check*/
numIsZero = 1;
iNum2 = 1;
iDen2 = 2;
}
else
{   printf("Invalid fraction.\n\n");
invalid = 1;
}

if((iNum2 > 20 || iDen2 == 0 || iDen2 > 20) && invalid == 0)
{   printf("Invalid fraction.  Allowed parameters- Numerator(0-20), Denominator(1-20)\n\n");
fracCheck = 1;
}

invalid = 0; /*re-initialize invalid*/
}   /*end of fraction 2 validation and formatting*/

if(frac1[0] == '\n')   /*check for a null enter*/
{   break;
}
if(numIsZero == 1)     /*check for a 0 numerator*/
{   printf("Product: 0");
break;
}

numProd = iNum1*iNum2;
iNum1 = numProd;     /*re-use num1 to store numProd and denProd*/
denProd = iDen1*iDen2;
iNum2 = denProd;

while(iNum1 != iNum2)  /*exits when GCD is found, when iNum1==iNum2*/
{	if(iNum1 > iNum2)
{	iNum1 -= iNum2;
}
else
{	iNum2 -= iNum1;
}
}

numProd = numProd/iNum1;
denProd = denProd/iNum1;
printf("%s%i/%i", "Product: ", numProd, denProd);
}while(nullEnter == 1);
}``````

I'm trying to parse the string to an int using atoi(), which should return a 0 when it is not an int. Lets say the user enters in a value: 1e/2, intCheck4 (I highlighted this in red) should return an int 0, but instead (i think) it only takes the first value and returns a 1, so it isn't validated properly. I can't validate it 1 character at a time because the numerator has to allow for a 0, and so if a user enters in a fraction: 0/2, it is a valid fraction but will not be accepted by the program.
Can anyone tell me if im doin something wrong here and/or how I should go about validating this otherwise. Thanks.

1 - don't use fgets, it's a security bug. Your program may well behave in a complete different way than you expect (dig for "buffer overflow" on the web) (Edit: this is wrong, I was thinking about gets, forget that sentence.)
2 - let's say you have read the string in a variable called fraction, you can do:

``````int num, den, nb_item;
nb_item = sscanf(fraction, "%d / %d", &num, &den);
if (nb_item != 2) /* error */;
if (num < 0 || num > 20) /* error */;
if (den < 1 || den > 20) /* error */;``````

Then you can play with den and num as you wish.
HTH.
Ah, how to read a string and avoid buffer overflow is another issue.
And some strings might also be accepted when they maybe shouldn't, like "2/3abc"

commented: Just an amasing security advice -5

> don't use fgets, it's a security bug.

Care to explain?

> don't use fgets, it's a security bug.

Care to explain?

Oops, sorry. Forget it. I was thinking about gets.
My apologies.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.18 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.