so I'm a complete newb to C and I'm struggling with the language. I need to write a program that will re-prompt a user to input a number if they input a negative number untill they produce a positive one. I have the below so far, no error messages are showing but when I type in a negative float value it does not re-prompt me, it just displays the number. Any ideas?
#include <cs50.h>
#include <stdio.h>
#include <math.h>
float get_positive_float(string prompt);
int main(void)
{
float f = get_float("Cash: ");
printf("%f\n", f);
}
float get_positive_float(string prompt)
{
float n;
do {
n = get_float("%s", prompt);
} while (n < 0);
return n;
}
float get_positive_float(char const *prompt)
{
float result;
while (prompt && printf(prompt), scanf(" %f", &result) != 1 || result < 0.f) {
fputs("Please only enter positive values!\n\n", stderr);
for (int ch; (ch = getchar()) != '\n' && ch != EOF;); // clear the rest of the line
}
return result;
}
A version using the thingies from <cs50.h> might look like that:
float get_positive_float(string prompt)
{
float result;
while ((result = get_float(prompt)), result < 0.f) {
fputs("Please only enter positive values!\n\n", stderr);
}
return result;
}
The problem though is, that floating point numbers aren't suitable for amounts of money. Use an integer type and calculate in cents. For output divide by 100.
Related
The task goes like this:
Write a program that calculates the power of a number (as a pow function from the "math.h" library), except the limitation here is that the exponent can only be an integer. The base and exponent are entered from the keyboard, where the base can be of the real type, while the exponent is a positive or negative integer. Attention should be paid to checking data entry; special treatment should be given to cases where the number is not entered and when the number entered is not an integer when entering the exponent!
Example input/output:
Enter a base number: abc
You didn't enter a number!
Enter a base number: 3.3
Enter exponent: something
You didn't enter a number!
Enter a base number: 3.3
Enter exponent: 5
3.3^5 = 391.354
Enter a base number: 12
Enter exponent: 2.5
Entered number is not an integer!
This is my code so far:
#include <stdio.h>
int main() {
double base, result = 1;
int exp, i;
printf("Enter a base number: ");
scanf("%lf", &base);
printf("Enter exponent: ");
scanf("%d", &exp);
for (i=1; i<=exp; i++) {
result *= base;
}
printf("%.2lf^%d = %.2lf", base,exp,result);
return 0;
}
It calculates the power of n successfully. But how do I add the "You didn't enter a number!" text when the input is wrong. Also, some results should be printed with 3 decimals, some with 6, etc.(depends on the result).
... how do I add the "You didn't enter a number!" text when the input is wrong.
To validate that a line of input is a double:
Do not use scanf() anywhere until you know why it is bad.
Instead, read the line of user input with fgets() which forms a string.
char buf[1024]; // Ample size buffer for very large and tiny precise values.
if (fgets(buf, sizeof buf, stdin)) {
double x;
int error_code = validate_double(buf, &x);
if (error_code == 0) printf("%.17g\n", x);
else printf("Error %d, invalid double <%s>\n", error_code, buf);
}
Validate with strdod()
int validate_double(const char *buf, double *x) {
errno = 0;
char *endptr;
*x = strtod(buf, &endptr);
if (buf == endptr) return 1; // Non numeric input
// First skip over trailing white-space
while (isspace(((const unsigned char *)endptr)[0])) {
endptr++;
}
if (*endptr) return 2; // Junk after numeric input
if (errno == ERANGE && (*x > 1.0 || *x < -1.0)) { // overflow
return 0; // or maybe 3 if you want to flag this
}
if (errno == ERANGE && (*x <= 1.0 && *x >= -1.0)) { // underflow
return 0; // or maybe 4 if you want to flag this
}
return 0;
}
To validate input is an integer, could use strtol() or the above and simply add.
double expo;
int error_code = validate_double(buf, &expo);
if (error_code == 0) {
if (!(expo >= 0.0 && expo <= INT_MAX && (int)expo == expo)) {
error_code = 5; // Out of +int range or non-integer.
}
}
... some results should be printed with 3 decimals, some with 6, etc.(depends on the result).
Try printing with %g with ample precision. This format does not print trailing precision '0' digits.
printf("%.17g\n", result);
Your exponentiation algorithm is [very] inefficient:
for (i = 1; i <= exp; i++) {
result *= base;
}
It is the equivalent of doing multiplication by repetitive addition.
To do it efficiently, do "exponentiation by squaring". See: https://en.wikipedia.org/wiki/Exponentiation_by_squaring
Change your loop to:
for (i = exp; i != 0; i /= 2) {
if (i % 2)
result *= base;
base *= base;
}
Also, look at the xpow function in the second code block of my recent answer: What's the problem in the code which was supposed to print Armstrong numbers up to 999
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");
}
So here is my code. Its a school assignment. I had to make a program to calculate the square root of a number using a method the Babylonians developed etc, that's not the important part. What I was wondering is if it's possible to ignore letters in my scanf so that when I input a letter it doesn't go berserk in my terminal. Any help is welcome and greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double root_Approach(double s); // defines the two functions
void ask_Number(void);
int main() {
ask_Number(); // calls function ask_Number
printf("\n\n");
system("pause");
return 0;
}
double root_Approach(double s) {
double approach;
approach = s;
printf("%.2lf\n", s); // prints initial value of the number
while (approach != sqrt(s)) { // keeps doing iteration of this algorithm until the root is deterimened
approach = (approach + (s / approach)) * 0.5;
printf("%lf\n", approach);
}
printf("The squareroot of %.2lf is %.2lf\n",s, sqrt(s)); // prints the root using the sqrt command, for double checking purposes
return approach;
}
void ask_Number(void) {
double number;
while (1) {
printf("Input a number greater than or equal to 0: "); // asks for a number
scanf_s("%lf", &number); // scans a number
if (number < 0) {
printf("That number was less than 0!!!!!!\n");
}
else {
break;
}
}
root_Approach(number);
}
Scanf reads whatever may be the input from the terminal (character or integer)
One way you can do is to check the return statement of scanf whether the read input is integer or not an integer.
Here is the sample code
int num;
char term;
if(scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
`
this link may be helpful
Check if a value from scanf is a number?
Program to limit the user's input to one decimal point in C.
For example:
Enter grade: 5 //Acceptable
Enter grade: 8.5 //Acceptable
Enter grade: 6.467 //Not acceptable, Re-enter grade
#include <stdio.h>
#include <math.h>
main()
{
double grade[8];
int i;
for (i = 0; i < 8; i++) {
printf("Insert grade: ");
scanf("%f", &grade[i]);
}
}
You will have to input the data as string, then check it only has one decimal place.
It is not possible to input a floating-point value and then check for decimal places; since the floating point values are stored internally with binary places and hold an approximation of the value that was input, in most cases.
The input code could look like:
char temp[20];
if ( 1 != scanf("%19s", temp) )
return EXIT_FAILURE;
// code to check for decimal place goes here - I'm purposefully not
// showing it as this looks like homework!
// once we have checked that the input is correct, then convert to double
grade[i] = strtod(temp, NULL);
#include <stdio.h> // printf(), scanf()
#include <math.h> // floor()
main()
{
double grade[8];
int i;
for (i = 0; i < 8; i++)
{
do
{
printf("Insert grade: ");
scanf("%lf", &grade[i]);
grade[i] *= 10;
if (grade[i] != floor(grade[i])) // Prints error message, if user types more than one decimal point
{
printf("Grade must have one decimal point.\nPlease re-enter grade.\n");
}
}while (grade[i] != floor(grade[i])); // Checks decimal point
}
}
Use fgets() to read the line into a buffer and then test that buffer.
char buf[99];
fgets(buf, sizeof buf, stdin);
// parse the line as a float - look for problems
char *endptr;
float f = strtof(buf, &endptr);
if (buf == endptr || *endptr != '\n') Fail_NonFloatInput();
// look for .
char *dot = strchr(buf, '.');
if (dot && isdigit(dot[1]) && isdigit(dot[2])) Fail_TooMuchPrecisison();
}
Alternatively code could try:
long long i;
int f;
if (2 != scanf("%lld.%1d", &i, &f)) Bad_Input();
float fl = i + f/10.0;
But that fails float input like 123456789012345678901234567890.0.
As #Matt McNabb says, read as text first.
You can use printf format specifiers to specificy the number of positions you are interested.
A format specifier follows this prototype: [see compatibility note below]
%[flags][width][.precision][length]specifier
Example from the cplusplus.com
#include <stdio.h>
int main()
{
printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
return 0
}
Output
floats: 3.14 +3e+000 3.141600E+000
More examples here http://www.cplusplus.com/reference/cstdio/printf/
#include <stdio.h>
#include <math.h>
int main()
{
int i;
int result;
float f;
while((result = scanf("%d", &i)) != EOF)
{
scanf("%f", &f);
printf("%.0f %.0f %.0f\n", floor(f), round(f), ceil(f));
}
printf("Done.\n");
return 0;
}
Hi,
I just began with C and I'm having a problem solving a question.
The problem is that with the user input, I need to get three sets of numbers that are floored, rounded, and ceiled. This process must be ongoing until the user stops by EOF command (Ctrl-D).
When I run my code above, input a value 3.1415, I get 0 0 1 as an output, which is wrong because it's supposed to be 3 3 4.
Any suggestions or help on how to fix the problem would be appreciated.
According to your code, you first need to input an integer value and then enter a float value.
OR, you can start accepting float value like this:
#include <stdio.h>
#include <math.h>
int main()
{
int result;
float f;
while((result = scanf("%f", &f)) != EOF)
{
printf("%.0f %.0f %.0f\n", floor(f), round(f), ceil(f));
}
printf("Done.\n");
return 0;
}
According to your code you need to input integer first then float, But if you enter float value first, that value read by i first and return 0 that is !=EOF, so second scanf does not wait for input, because it is inside the while loop. So always you will get 0 0 1 for all inputs!
To scan a number inside while loop use-
if (scanf("%f", &f) == 0) {
printf("Err. . .\n");
do {
c = getchar();
}
while (!isdigit(c));
ungetc(c, stdin);
Else scan float value first instead of int and float. Try this code-
while((result = scanf("%f", &f)) != EOF)
{
printf("%.0f %.0f %.0f\n", floor(f), round(f), ceil(f));
}
printf("Done.\n");