I'm currently working on a banking terminal program for the laboratory exercises at my university.
What puts me off my stride is a function supposed to take the user's input of amount to be transfered, check if it fits all requirements and if so, returns the value provided to the program.
Our tutor is mad about all means of securing the input, and so I have to call an error on any kind of inconsistency. Value too high? Error. Negative or zero value? Error. A number more precise than 0.01? Error. Non-digit-non-dot characters in the input? Error.
Due to that, my function is definately overcomplicated, yet I'm fine with that. What drives me up the wall is the fact, that both atof()
and strtod()
functions reads numbers in a somehow wrong way.
long double take_amount()
{
char input[21];
bool success, correct;
unsigned long int control1;
long double amount, control, control2, control3;
do
{
success = true, correct = true;
printf("\t\tAmount:\t\t");
success = scanf("%20[^ \t\n]c", input);
__fpurge(stdin);
correct = check(input, 'b');
amount = strtod(input, NULL);
printf("\n\tGOT %.20Lf\n", amount); ///
control = amount * 100;
control1 = (unsigned long int)floor(control);
control2 = (long double) control1;
control3 = control2 - control;
printf("\n\tGOT2 %.20Lf\n", control3); ///
if (control3 != 0)
{
if (control3 >= 1 || control3 <= -1)
{
printf("\n\t\tWe are sorry, but for the safety reasons it is impossible to transfer");
printf("\n\t\tsuch a great amounts while online. If you really wish to finalize");
printf("\n\t\tthis operation, please, visit the closest division of our bank.");
printf("\n\t\tWe are sory for the inconvenience and wish you a pleasent day.");
press_enter();
}
correct = false;
printf("\nDAMN\n"); ///
}
if (amount <= 0)
{
correct = false;
printf("\nGOD DAMN\n"); ///
}
if(success == false || correct == false)
{
printf("\n\t\tInvalid input, please try again.\n\n");
}
else
{
printf("\t\t\t\t%.2Lf\n", amount);
printf("\n\t\tIs it correct input? ((Y)es/(N)o/(E)xit)");
if (accept())
{
break;
}
else
{
continue;
}
break;
}
}while (1);
return amount;
As far as my functions used here goes, check()
checks if the string contains only legal characters (digits and dot), press_enter()
waits for enter-press to leave to main menu and accept()
reads only y/n/e, return true
on y, false
on n and leaves to menu on e.
The lengthy part with control variables is my solution for checking if the number is not more precise than 0.01. Sadly, it doesn't work due to strtod()
.
My problem is that strtod()
doesn't really work! Even with really medicore numbers, being far from underflow or overflow, the value returned doesn't match the input. Some examples:
Enter the amount you would like to deposit. Amount: 1234.45 GOT 1234.45000000000004547474 Enter the amount you would like to deposit. Amount: 0.999 GOT 0.99899999999999999911
It is not unlikely that it's my fault, but after several hours with this code I still couldn't come up with a working solution and that's why I'm asking for you help, vise internauts of Stack Overflow.
Is there any way to fix the reading of strtod()
? If not, is there another way to take that input that let's me check all that needs to be checked?
EDIT: ATTENTION, PLEASE!
If I haven't stated already, that my tutor is not the easiest guy to work with, I do so now.
He FORCES us to use DOUBLE format to hold the BALANCE stored on accounts. I know it because one of my collegues got his program REJECTED for using two-int, dollar - cent construction.
I highly appreciate you help here, so can you somehow solve that problem? I HAVE TO use double type to store the money. I also HAVE to check if there were no letters in the input (scanf()
set on %Lf
will just cut all non-digits from the end), HAVE TO check if the input is not more precise then 0.01, HAVE TO accept xxx.xx structure of the input. Any suggestions?