Simple C program not calculating correctly - c

So, I'm completely new to programming, and I'm learning to program C. I'm trying to write a simple program in C to calculate commission as follows
#include<stdio.h>
int main()
{
float fRate, fSales_Price, fCost, fCommission;
printf("\nEnter your commission rate: ");
scanf("%.2f",&fRate);
printf("\nEnter the price of the item sold: ");
scanf("%.2f", &fSales_Price);
printf("\nEnter the original cost of the item: ");
scanf("%.2f", &fCost);
fCommission = (fRate / 100) * (fSales_Price - fCost);
printf("\nYour commission is: %.2f", fCommission);
}
Whenever I try to run it, two things happen. First, if I try to enter any decimals into the program, e.g. if I said the rate was 12.5, it immediately skips the other inputs and completes the program, saying commission is 0.00. If I ignore decimals, the program runs fine until the end, when I still get commission as 0.00. Any suggestions?

Your format specifier is wrong, you must use compiler warnings if you do, then you wouldn't be asking this, because that format specifier is invalid, you cannot limit the number of decimal places with scanf() it's been discussed in many questions on SO, more importantly you don't need to, and it wouldn't be meaningful, so just remove the .2 from your format specifier, and instead, check that scanf() succeeded before using the values.

"%.2f" is an illegal format string for scanf, so your code causes undefined behaviour. The correct format string is "%f".
Also you should check the result of scanf. If scanf fails, the bad data is not consumed from the input and so subsequent scanfs fail too (this is why you see the other inputs skipped).
For example:
if ( 1 != scanf("%f", &fRate) )
{
printf("Invalid input for fRate.\n");
exit(EXIT_FAILURE);
}

"%.2f" is not a valid format for scanf. See scanf() manual page for details.
The easiest format to use is "%f".
Also, it's a good practice to check the return value of scanf so you know when the operation was successful.
if ( scanf("%f", &fRate) != 1 )
{
// Error reading the data.
// Deal with the error.
}

Related

Can't understand why I can't loop %[^/n]

I can't seem to find where the problem is in here.
During the first loop, I can enter the name of the creditor but I can't do that during the second loop.
int main(){
float cb,ir,si,sum=0,totaldebt;
int time,i;
char name[25];
printf("------------Welcome to Debt Management System-------------");
for (i=1;i>=1;i++){
printf("\n%d)Name of the creditor: ",i);
scanf("%[^\n]",&name);
printf("Enter your current balance: ");
scanf("%f",&cb);
printf("Enter its interest rate: ");
scanf("%f",&ir);
printf("Enter time for the loan: ");
scanf("%d",&time);
si=cb*ir*time/100;//simple interest
totaldebt=si+cb; //simple interest + current balance
if (name=='none'){
break;
}
sum+=totaldebt;
}
It skip the scanf part and I somewhat guess that the reading part seems stuck by it's previous reading.
To get the effect you seem to be after, %[^\n]*c should be %[^\n]%*c. You need a specifier for the first pattern and then a specifier for a single character. The way you have it written now has you asking scanf to match everything up to a newline, and then read the sequence *c.
It can't read that sequence, but it matches the first specifier. So you end up with an unconsumed newline that is probably tripping your other input.
There's also the potential problem of your for (i=1;i>=1;i++), that condition is fishy, and likely to go on for a while.
Now, while this is all probably a fun exercise, I suggest you ditch scanf and switch to fgets to read lines of input. It's less cryptic, and it forces you to pass a buffer size, which makes using it somewhat easier and safer compared to scanf.
To complete the first answer, I noticed this problem:
if (name=='none')
{
break;
}
This form is not correct in C, you should:
use strcmp
function,
use " instead of ' to define a string:
/* if two strings are the same --but not necessary at the same adress-- strcmp return 0*/
if (0 == strcmp(name, "none"))
{
break;
}
While taking a string input you are not required to use the reference operator '&'. That's why in your first scanf statement use name instead of &name. Also modify the input statement with %*c if you want to take newline character in the input as shown below. Other errors have been stated in the above answers.
scanf("%[^\n]",name); OR
scanf("%[^\n]%*c",name);

why my c program doesn't crash when i entered the wrong data type

I'm new to c and I'm writing a basic program that ask the user for input
#include <stdio.h>
int main(void){
float weight;
printf("enter your weight in kg:\n");
fflush(stdout);
scanf("%f", &weight);
printf("your weight is %f kg\n", weight);
return 0;
}
Everything works as expected when I under a number when asked for input. But when I accidentally entered words, the program doesn't crash and instead print out your weight is 0.00000 kg.
I was just wondering, why doesn't my program crash when it expect numbers but I have entered words? and why did it printed out 0.00000?
why my c program doesn't crash when i entered the wrong data type
When a user of your program enters some input that can't be converted by scanf to a float, the variable weight will not be initialized. So when the program prints the variable, it will read an uninitialized float. According to the c standard, that has undefined behavior.
However, undefined behavior does not guarantee a program crash. It may crash or it may continue execution. We can't know as it is undefined what will happen. On your system execution just continued but on another system a program may happen.
On many systems the memory allocated to a program as startup is initialized to all zeros. Therefore variables in main is (often) an all zero binary pattern when left uninitialized. For floats that translate to the value 0.0
So even if you don't initialize weight it seems as if it was initialized to zero and your program runs fine even with input like abc and prints the weight as 0.0
However, from a standard point of view it is still undefined behavior to read an uninitialized float variable
If you did the same inside a function that you called a number of times (with other function calls in between), you would see strange behavior sooner or later.
Typically just a print of strange values but on some systems, you might see a crash (but that is more rare).
You should do:
if (scanf("%f", &weight) == 1)
printf("your weight is %f kg\n", weight);
else
printf("Illegal input\n");
Every input the user gives in C is treated as a string, though the input you provide is in numbers. After getting the input from the user, it is converted in to numeric data using atoi (ascii to integer) function (man atoi). The return value of this function is the converted value. Upon successfully converting the given string to an integer it returns the converted integer value and it returns zero when the resultant value is a non-integer. This is the reason why it is not showing any error when you input different data.
Try the same code with different format specifiers, so that you can have a clear understanding.
The MAN page of scanf :
Return Value
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in
the event of an early matching failure.
So, scanf return the number of arguments successfully scanned. that's why your program not crashing.
the program does not crash because the input does nothing to cause a crash.
However, the posted code does have a major flaw. This line:
scanf("%f", &weight);
should be:
if( 1 != scanf("%f", &weight) )
{
perror( "scanf failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
In other words, always check system functions for errors, especially those that are performing input.

to calculate remaining loan balance

I am trying to write a program in C to calculate the remaining balance after 1st, 2nd & 3rd monthly payments, given the loan, monthly payment amount, and interest rate. I am having a problem in entering the input (floating point numbers) i.e it only takes one input (loan) & displays the answer without considering the other 2 inputs (interest rate & monthly payments).
This problem occurs only when I use the floating-point numbers (even in other programs also). I want to ask if this is due to coding or due to any other reason.
My code is as follows:
#include<stdio.h>
main()
{
float loan,interest,monthly_payment;
float balance_Imonth,balance_IImonth,balance_IIImonth;
printf("Enter the amount of loan: ");
scanf("%.2f",&loan);
printf("Enter the amount of interest: ");
scanf("%.2f",&interest);
printf("Enter the amount of monthly payment: ");
scanf("%.2f",&monthly_payment);
balance_Imonth=((interest/(100*12))*loan)+(loan)-(monthly_payment);
balance_IImonth=((interest/(100*12))*loan)+(balance_Imonth)- (monthly_payment);
balance_IIImonth=((interest/(100*12))*loan)+(balance_IImonth)-(monthly_payment);
printf("Balance remaining after I payment: $%.2f\n",balance_Imonth);
printf("Balance remaining after II payment: $%.2f\n",balance_IImonth);
printf("Balance remaining after III payment: $%.2f\n",balance_IIImonth);
}
The format specification "%.2f" is OK for printf but not for scanf. Use just "%f".
In your program, all the scanf function calls fail. You are just seeing undefined behavior due to use of uninitialized variables.
Always check the return value of scanf to make sure that the operation succeeded before you proceed to use the variables in which scanf stores the results.
Use
if ( scanf("%f", &loan) != 1 )
{
// Deal with error.
}

Invalid conversion identifier '.'

So I'm writing code to interpret a users input about whether they're payed an hourly wage or set salary. I've started a switch statement and the first statement within it is a printf() & a scanf() statement that reads
printf("Enter hourly wage: ");
scanf("\n $%5.2d", &hRate);
the compiler keeps giving me an error message for the scanf() statement that says: "invalid conversion specifier . ".
I've gone through and checked the program, and I've tried changing the statement, taking out the $ and what not, and nothing seems to work.
Any thoughts?
scanf does not allow an optional . in a conversion specification.
. can be used with some printf conversion specifiers.
scanf("%5d", &hRate); // allowed
scanf("%5.2d", &hRate); // not allowed
printf("%5.2d", hRate); // allowed
'.' is not a valid part of a format specifier for "%d".
Anyway, the value you need to read is certainly of the form " $ xxx.xx"
Read the hourly wage as a floating point value.
printf("Enter hourly wage: ");
double dhRate;
if (scanf(" $%lf", &dhRate) != 1) Handle_BadInput();
// covert to cents if needed
int hRate = round(dhRate * 100.0);
Another approach would read as dollars and cents
printf("Enter hourly wage: ");
int hRate_d, hRate_c;
if (scanf(" $%d.%d", &hRate_d, &hRate_c) != 2) Handle_BadInput();
// covert to cents if needed
int hRate = hRate_d * 100 + hRate_c;
A better solution would read the entire line using fgets() and then parse it using sscanf(), strtol(), etc.

C programming elementary problem

#include <stdio.h>
#include <math.h>
int main (void)
{
float inches;
printf("Enter the number of inches\n");
scanf("%f\n",&inches);
float feet;
float cm;
float yards;
float meter;
feet = 12 * inches;
cm = 2.54 * inches;
yards = 36 * inches;
meter = 39.37 * inches;
printf("Amount in feet: %f\n", &feet);
printf("Amount in cm: %f\n", &cm);
printf("Amount in yards: %f\n", &yards);
printf("Amount in meters: %f\n", &meter);
getchar();
return 0;
}
I'm using Dev c++
Is the problem i'm problem I'm working on in C. Basically enter in a number in inches then print amount in cm,yards,meters and feet. This is giving me 0.0000 or something for all of them or actually the time it is up. I can't keep the screen up and I thought that was the purpose of getchar() but I must have been mistaken. Any help is great. Thanks!
EDIT 1
What about as far as keeping dev c++ on the screen instead of closing out after I put stuff in? I am also having to put 2 values in before it returns in anything when the screen pops up? Why??
Two problems:
The usual problem with using scanf(), in that it leaves the newline after the number unread and the following read operation (the getchar() here) reads it.
You shouldn't pass pointers to printf(), but the actual values.
You're trying to print the addresses of your floats as floats, you just want to say this:
printf("Amount in feet: %f\n", feet);
Note the lack of an address (&) operator on feet. You want to apply similar changes to your other printf calls.
With printf, you don't give it the address of the float values, you just give it the values. Remove the &s from the printf calls.
You need the address in scanf because the function modifies the variables that you pass in, but printf just needs the values. As it is, the printf is essentially reinterpreting the pointers as floats, which is why you get the garbage values displayed.
About I can't keep the screen up, it's a common problem to everyone trying to execute a console program in a graphical environment directly from the IDE, in particular Dev-C++. The problem is that there's no console for I/O, then one is provided but just for the time the program is running, and since programs are fast, if you do not add a pause after your last input and output, you won't have the time to read the output.
Many MS Windows Dev-C++ users add an horrorific system("pause"). I always suggest that, if Dev-C++ is not able to provide a console for I/O with the option "keep it opened even after the program ends", then it is better you open a shell (cmd or powershell on windows) and run your program directly from there.
About the input problem, unluckly scanf-ing has several buffering problem since the input that is not recognized for the given format is not discarded and is ready for the next reading. E.g.
scanf("%f", &aFloat);
scanf("%f", &theNextFloat); // in your case you have the extra getchar();
won't stop for the second scanf if you write 1.25 4.5 as first input, since the 4.5 is already available for the next scanf. In your case it was a newline that was left in the buffer and since getchar has found it, it does not need to wait for input. You could use a
while( getchar() != EOF ) ; instead, and then to exit you need to hit Ctrl-D.

Resources