Working with scanf and loops in functions - c

I want to use a function to ask the user for a balance. If the balance is below 0 the user is prompted to enter a value above 0. Here is the code I have done so far:
#include <stdio.h>
#include <string.h>
float getPositiveValue();
int main()
{
float begbal;
begbal = getPositiveValue();
getPositiveValue();
printf("balance: %f\n", begbal);
return 0;
}
float getPositiveValue()
{
float money;
printf("Please enter the beginning balance: \n");
scanf("%f", &money);
if(money < 0)
{
printf("Enter a balance amount above 0:");
scanf("%f", &money);
}else{
}
}
I get the error "warning: control reaches end of non-void function". I know I need to end the else statement, but not sure what to put in there if they did enter a value above 0. Also, when the program is run it asks the user twice to enter the beginning balance for some reason. Seems like this should be a simple fix, for some reason I have trouble getting my head around functions heh.
Any help much appreciated.
revised working code(thanks):
#include <stdio.h>
#include <string.h>
float getPositiveValue();
int main()
{
float begbal;
begbal = getPositiveValue();
printf("balance: %f\n", begbal);
return 0;
}
float getPositiveValue()
{
float money;
printf("Please enter the beginning balance: \n");
scanf("%f", &money);
while(money < 0)
{
printf("Enter a balance amount above 0:");
scanf("%f", &money);
}
return money;
}

getPositiveValue() is supposed to return a value (float). You could add return money; before its closing }.
What if the user is particularly dense and doesn't enter a positive amount? Do you want to give them only one chance? If not, you probably want to use a while (money < 0.0) loop.

You need to return a float value, so in this case you can return money.
You are calling your function twice in the main function.
begbal = getPositiveValue();
getPositiveValue();
Just remove the last statement

"Also, when the program is run it asks the user twice to enter the
beginning balance for some reason."
because you have called function getPositiveValue() TWICE IN YOUR CODE
and your function needs to return the float value which is "money" in this case.

The user could persist in entering the wrong thing, so you need a loop to iterate till they get it right. Also, you need to return a value from this function.
float getPositiveValue()
{
float money;
fputs("Please enter the beginning balance: ", stdout);
for (;;) {
scanf("%f\n", &money);
if (money >= 0)
break;
fputs("Balance must be nonnegative.\n"
"Please enter the beginning balance: ", stdout);
}
return money;
}
But that's only the tip of the iceberg here. scanf should never be used, and floating-point numbers should not be used to keep track of money. What you should really be doing here is reading a line of text with getline (or fgets, if getline is unavailable), and parsing it with strtoul and custom logic, presumably as [$]dddd[.cc] (where square brackets indicate optional text), into a uint64_t value scaled to cents.

As the user may enter an invalid range (a negative number) or non-numeric text, need to consume offending input before next prompt.
float getPositiveValue() {
float money = 0.0;
printf("Enter a balance amount above 0:");
while ((scanf("%f", &money) != 1) || (money < 0)) {
int ch;
while (((ch = fgetc(stdin)) != '\n') && (c != EOF));
if (c == EOF) break;
printf("Enter a balance amount above 0:");
}
return money;
}

Related

multiply numbers untill the user enters 0

I don't know why but the loop doesn't stop even when I enter 0. can someone help me with this?
int main(void)
{
float number,product = 1;
printf("Provide floats separated by a line: \n");
scanf("%f" , &number);
while(number != 0)
{
product *= number;
if(number == 0)
break;
}
printf("The product of your values is: %.2f" , product);
printf("\n");
}
You'll need to place the scanf call inside the loop to repeatedly ask the user for input. As it is you only ask once, and then loop forever on the same value.
Here we place the call in the predicate itself:
#include <stdio.h>
int main(void) {
float number = 0,
product = 1;
puts("Provide floats separated by a line:");
while (scanf("%f" , &number) == 1 && number)
product *= number;
printf("The product of your values is: %.2f\n" , product);
}
You should always check the return values of your I/O functions. scanf returns the number of conversions that took place, which here should be 1. On error, EOF, or number being 0 we do not continue the loop.

Isalpha is requiring an identifier

Here's my code:
#include <stdio.h>
#include <ctype.h>
main(){
float input;
printf("Input: ");
scanf("%f", &input);
if (isalpha(input) || (input) < 0)){
printf("Input is an alphabet or is lesser than 0");
} else {
printf("Input is correct. %f is a number larger than 0", input);
}
}
I want the code to detect if input is a number larger than 0, or is it an alphabet. However, I am getting this error:
8: error: identifier expected
What does it mean to my code's execution? How am I supposed to run the code successfully?
Correct parentheses in if:
if ( isalpha(input) || (input < 0) )
In addition, you need to check the return value of scanf() whether there was input or not. In the case of no input, the return value would be 0 or in case of multiple inputs how many succeeded. In your case, you can use the return value to determine whether a float was input or not.
The main() should return an int and always initialize your variables.
Example (live):
#include <stdio.h>
#include <ctype.h>
int main()
{
float input = 0.0f;
printf("Input: ");
int ret = scanf("%f", &input);
if ( ret == 0 )
{
printf("ERROR: Input is NOT a float!\n");
return -1;
}
if ( input < 0.0f )
{
printf("Input is less than 0");
}
else
{
printf("Input is correct. %f is a number larger than 0", input);
}
return 0;
}
Your parentheses aren't opened/closed properly.
Maybe your ide/compiler is taking care of it, but it should be int main()
isalpha() will behave unexpectedly with float values. Try avoiding that.
First of all you are missing int declaring main,
int main()
Also,you have excessive bracket in line
if (isalpha(input) || (input) < 0)){
Scanf uses %f to read floats. What your program will do is accept any ascii character and I suppose that wasn't your intention.
I am still not sure what you need, but you could try something like this as a starting point. It does not handle all possible inputs, and will erroneously classify an input such as #42 as alphabet or lesser than 0, which is questionable, but you can iterate on this and hopefully get to a more polished version.
#include <stdio.h>
#include <ctype.h>
int main(){
float input;
printf("Input: ");
if (scanf("%f", &input) && input >= 0){
printf("Input is correct. %f is a number larger than 0", input);
} else {
printf("Input is an alphabet or is lesser than 0");
}
}
Explanation
We save the value in input, if compatible with the %f format:
float input;
Prompt for the user:
printf("Input: ");
This condition is made of two parts; the first part is the scanf, that will try to read input, and if successful will evaluate to 1, which is true, so the second part input >= 0 will be evaluated, and if input is indeed >= 0 we print the first message.
if (scanf("%f", &input) && input >= 0){
printf("Input is correct. %f is a number larger than 0", input);
Else we print the second message.
} else {
printf("Input is an alphabet or is lesser than 0");
}

Scanning Values Until Getting a Significant Character in C

For my homework, I am trying to code a calculator which can also calculate average of taken numbers. I don't want to ask for number of numbers because our teacher don't want it in that way. So I thought of scanning values until the user presses "p". But as you would guess, the numbers are float and "p" is a character. What I want to do is assigning the value scanned to both of them if it is possible. I tried different ways, played with the codes but it isn't working properly. So I am seeking your advice.
It prints a value when p is inputted as like 3rd, 5th, 7th (oddth) number (sometimes right, sometimes wrong but I can fix it if I figure this out). But it doesn't print a value in other occasions and expects infinite inputs from the user.
This is the code I have written for this. scanf("%f %c", &number1, &pause); command is where I want to know about, actually.
#include<stdio.h>
float number1, number2, i, result;
char pause;
int main() {
scanf("%f", &number1);
i = 0;
while (pause != 'p') {
number2 = number1 + number2;
scanf("%f %c", &number1, &pause);
i++;
}
result = number2 / (i - 1);
printf("%f", result);
}
Use double not floats if there is no specific reason to do so (like using uC without double FPU).
You do not initialize the variables
Always check the result of the I/O operation.
#include <stdio.h>
int main ()
{
double number1= 0, number2 = 0, i = 0, result = 0;
char pause = 0;
char line[128];
while (pause != 'p')
{
if(fgets(line, sizeof(line), stdin))
{
if(sscanf(line, "%lf %c",&number1, &pause) != 2)
{
printf("Wrong input - try again\n");
pause = 0;
continue;
}
number2 = number1 + number2;
i++;
}
else
{
// do something with I/O error
}
}
result = number2 / (i-1);
printf("%lf",result);
}
You can play with it yourself : https://onlinegdb.com/Hy3y94-3r
I noticed 3 problems with your code.
First I would advise you to use meaningful variables names. number1, number2, etc. and the i which represents the number of inputs given can be an int instead of a float.
Secondly, you lack of printing to the user what's going on in your program; it's better to have messages like "enter your number, do you wanna stop? the result is...etc".
Lastly, having two inputs in one line of code can make it hard to debug, knowing that reading strings and characters in C is already hard for beginners. For example, %c does not skip whitespace before converting a character and can get newline character from the previous data entry.
Here is my fix: I changed some variables' names, printed some messages and read the two inputs in two different lines with adding scanf(" %c") with the space to avoid that problem.
#include<stdio.h>
float sum, temp, result;
int nb;
char pause;
int main () {
pause='a';
while (pause != 'p'){
printf("Enter your number: ");
scanf("%f",&temp);
sum+=temp;
nb++;
printf("type 'p' if you want to stop: ");
scanf(" %c",&pause);
}
result = sum / nb;
printf("the average is : %f",result);
}
I tested it, should work fine
Edit: after explaining that you don't want to ask the user each time, here is how the code should work (the case that the user don't input a float is not treated, and just take it as zero
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
float sum, temp, result;
int nb;
char input[50];
int main () {
sum=0;
nb=0;
printf("Enter your numbers, then type 'p' to stop\n");
do{
printf("Enter your next number: ");
scanf("%s", input);
if(strcmp(input,"p")!=0)
{
float temp= atof(input);
sum+=temp;
nb++;
}
}while(strcmp(input,"p")!=0);
if(nb!=0)
result = sum / nb;
printf("\nThe average is : %f",result);
}

C: Program won't ask the user again if the user inputs a character using fflush(stdin)

Obviously I'm not going to post my whole code here as it IS very long, it is a tax calculator after all. This problem applies to all my scanfs that need double values as input from the user. Basically as the title says, my program doesn't ask the user to input another value even if it's a character, which obviously isn't a double value so some help will be very appreciated. Forgive me as I'm still in the first year of my course and don't know everything about programming.
double salary;
printf("This program will compute your yearly and monthly witholding tax for you \n");
printf("How much is your total monthly salary? ");
fflush(stdin);
scanf("%lf", &salary);
while (salary < 0)
{
printf("\n");
printf("Invalid Input\n");
printf("How much is your total monthly salary? ");
fflush(stdin);
scanf("%lf", &salary);
}
You correctly diagnosed the problem: invalid input stays in the input buffer, causing every subsequent scanf to fail. You cannot correct this with fflush, because it is not defined for input streams. Note that you also misuse scanf as you do not test the return value.
The simple and generic solution to your problem is this: replace calls to scanf with calls to a function that reads a line from the user and parses it as a string repeatedly until either EOF or correct input is entered.
This function takes a range for validity checking. You can pass infinities if you dont want to accept all input.
int getvalue(const char *prompt, double *vp, double low, double high) {
char buffer[128];
for (;;) {
printf("%s ", prompt);
if (!fgets(buffer, sizeof buffer, stdin)) {
printf("EOF reached, aborting\n");
// you can also return -1 and have the caller take appropriate action
exit(1);
}
if (sscanf(buffer, "%lf", vp) == 1 && *vp >= low && *vp <= high)
return 0;
printf("invalid input\n");
}
}
In your code fragment, you would replace everything with this:
double salary;
printf("This program will compute your yearly and monthly withholding tax for you\n");
getvalue("How much is your total monthly salary?", &salary, 0.0, HUGE_VAL);
HUGE_VAL is defined in <math.h>, but its value seem a bit high for a salary anyway, you can just write a decent maximum such as 1E9.

While loop for only accepting integer value and exiting on any other input

I'm running this program in C to convert Fahrenheit to Celsius and need to accept only integer value from the user.
Please tell me how I can modify this?
int main() {
int x;
double y;
while(x>0) {
printf("Enter the temperature in Fahrenheit:");
scanf("%d", &x);
y=((x-32)/1.8)
printf("%f\n",y);
}
}
The reason your code does not work is that sometimes scanf does not read anything, so it does not modify x.
You know that scanf read something by checking its return value. It returns the number of "scanned" items. In this case, the number must be 1.
When scanf returns 0 instead, you should read and discard the data in the buffer. You do it by supplying %*[^\n] format specifier, which means "read and discard input up to '\n' character. The complete snippet that reads an int until success looks like this:
while (scanf("%d", &x) != 1) {
printf("Please enter a valid number:");
scanf("%*[^\n]");
}
Note: It goes without saying that you should fix your syntax error with the missing semicolon ; on the line that computes y.
You can use below code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
double y;
char str1[5];
int num1,i;
bool yes = true;
while(x>0)
{
printf("Enter the temperature in Fahrenheit:");
scanf("%s",str1);
for(i=0;str1[i]!='\0';i++)
if(!(str1[i]>=48&&str1[i]<=56))
{
printf("The value is invalid \n");
yes = false;
}
num1 = atoi(str1);
if(yes == true)
{
printf("This Number is %d\n",num1);
y=((num1-32)/1.8);
printf("%f\n",y);
}
}
}

Resources