This question already has answers here:
Avoid trailing zeroes in printf()
(16 answers)
Print float/double without trailing zeros? [duplicate]
(5 answers)
Closed 1 year ago.
How can I variably influence the number of digits printed in C program?I do not want to write unnecessary zeros in decimal development
x=7
Output: 7
x=7.700
Output 7.7
x=7.77700
Output: 7.777
My point is not to have fixed printf ("%. 3lf", yourVariable); , but but it changed variably on the values I would send there
You can make use of %g Format Specifier in C for this.
Working Fiddle
Working Code
#include <stdio.h>
int main() {
float number;
printf("Enter an integer: ");
// reads and stores input
scanf("%f", &number);
// displays output
printf("You entered: %g", number);
return 0;
}
I believe what you are looking for is a way to dynamically change the precision of the output without having to hardcode it.
If you have access to a c99 compiler, you can generate format strings by using snprintf like:
char* format_width(double x, unsigned prec) {
int fmt_size = snprintf (NULL, 0, "%%.%ulf", prec);
char* fmt_string = malloc(fmt_size + 1);
snprintf(fmt_string, fmt_size + 1, "%%.%ulf", prec);
int out_size = snprintf (NULL, 0, fmt_string, x);
char* out_string = malloc(out_size + 1);
snprintf(out_string, out_size + 1, fmt_string, x);
free(fmt_string);
return out_string;
}
Usage could be something like
int main() {
double number;
unsigned prec;
printf("Enter a number: ");
// reads and stores input
scanf("%lf", &number);
printf("Enter precision: ");
// reads and stores precision
scanf("%u", &prec);
char* result = format_width(number, prec);
// displays output
printf("You entered: %s", result);
free(result);
return 0;
}
Demo
Optimizing allocations
In order to avoid too many allocations, one could make use of a buffer of reasonable size to generate the format specifier. For example, it is very unlikely that the fmt_string will ever exceed 15 characters, so we can optimize that part.
It may also be possible that the user already knows the maximum size of input they may ever receive, so we can allow them to pass in the out_string buffer (which is assumed to be large enough to contain the result)
char* format_width(double x, unsigned prec, char* out_string) {
static char fmt_string[15];
snprintf(fmt_string, 15, "%%.%ulf", prec);
int out_size = snprintf (NULL, 0, fmt_string, x);
snprintf(out_string, out_size + 1, fmt_string, x);
return out_string;
}
You can simply convert it to a float number
x = (float)x;
IT will remove all the unnecessary 0.
Related
When I enter 2, I wish to get this output:
value: 2.4
But when I do the multiplication, I am getting this:
value: 2.400000
This is my code:
#include <stdio.h>
int main()
{
float num;
float result;
printf("Number: ");
scanf("%f", &num);
result = num * 1.2;
printf("Result: %f", result);
}
What can I do?
You can specify how many digits you want to print after the decimal point by using %.Nf where N is the number of digits after the decimal point. In your use case, %.1f: printf("Result: %.1f", result).
There are some other issues in your code. You are making use of scanf(), but you are not checking its return value. This may cause your code to break.
scanf() returns the number of arguments it successfully parsed. If, for any reason, it fails, it doesn't alter the arguments you gave it, and it leaves the input buffer intact. This means whenever you try again and read from the input buffer, it will automatically fail since
it previously failed to parse it, and
it didn't clear it, so it's always there.
This will result in an infinite loop.
To solve the issue, you need to clear the input buffer in case scanf() fails. By clearing the buffer, I mean read and discard everything up until a newline (when you previously pressed Enter) is encountered.
void getfloat(const char *message, float *f)
{
while (true) {
printf("%s: ", message);
int rc = scanf("%f", f);
if (rc == 1 || rc == EOF) break; // Break if the user entered a "valid" float number, or EOF is encountered.
scanf("%*[^\n]"); // Read an discard everything up until a newline is found.
}
}
You can use it in your main like that:
int main(void) // Note the void here when a function doesn't take any arguments
{
float num;
float result;
getfloat("Number", &num);
result = num * 1.2;
printf("Result: %.1f", result); // Print only one digit after the decimal point.
}
Sample output:
Number: x
Number: x12.45
Number: 12.75
Result: 15.3
I am trying to make a program that calculate the width or how many numbers a float contains. I need this to make good looking outputs in console. For example, the width of the following numbers are:
4 (1)
23 (2)
0.3 (3 because the . has the width of one)
0.45 (4)
12.34 (5)
0 (1)
I have tried to check if the number == 0 then the width is 1 and done, and else multiply the number with 10 until there is no decimals float == (int)float and then calculating how many times it is needed to divide by 10 to get a number float < 0. I have tried everything I have found at the internet without any real luck...
Just use snprintf for counting length of what you want to print, like this:
int main()
{
float num;
int len;
if (1 == scanf("%f", &num)) {
len = snprintf(NULL, 0, "%g", num);
printf("%g (%d)\n", num, len);
}
return 0;
}
You could try to convert float to the string.
You may use snprintf or something similar for your needs.
The precision of the conversion of the snprintf may not be best.
You may want to limit number of characters after the '.'.
#include <stdio.h>
#include <string.h>
int main(void)
{
float num = -12345.678;
char str[32];
size_t counter = 0;
// freestyle solution
int len;
printf("Please input the number:\n");
if (1 == scanf("%f", &num)) {
len = snprintf(NULL, 0, "%g", num);
printf("\%g (%d)\n", num, len);
}
//sg7: improved one - '.' and '-' counted.
len = snprintf(str, 32, "%f", num);
printf("\n%s Number of characters: %zu",str, len);
return 0;
}
Test:
Please input the number:
-12.345678
-12.3457 (8)
-12.345678 Number of characters: 10
Assuming your float is stored in the variable f, you can do this:
int width; char buffer[50];
width = sprintf(buffer,"%f",f);
Please keep in mind that floats are usually stored with a precision of six digits after the decimal point, so a number like 14.2 is stored as 14.200000 thus having a width of 9 instead of 4. It might be stored as 13.999999 as well so keep that in mind.
int main()
{
double a = 1;
double b = 3;
int n = 128;
int answer = 0;
printf("select an option(1, 2) ");
scanf("%d", answer);
double y = calcIntegral (answer, a, b, n);
printf("%f \n", y);
system("pause");
return 0;
}
it gets to Scanf and then if accepts the answer but stalls completely and I have to force the task to end. What's going on? This is identical to other programs I've written, I think. I tried using %i as well, and using a char instead of a double for the variable "answer". It says it can't access the memory.
For scanf with modifier d, it matches an optionally signed decimal integer, and the next pointer must be a pointer to int. Says the standard. Also make sure always check scanf return value.
int ret = scanf("%d", &answer);
if (ret != 1) {
// failed to input the number
}
When using scanf(), the variable you read has to be a pointer . So your statement :
scanf("%d", answer);
should be :
scanf("%d", &answer);
as you have declared answer to be an int, so its memory address is a pointer to an int.
On the other hand, if you wanted to read a string and had declared :
char *str;
allocating some memory for it, then the statement would be :
scanf("%s", str);
as str is declared as a pointer to char.
as expected this prog. should accept a number until it encounters a 4 but it gives some garbage value. why?
int main(void)
{
int a;
printf("Enter a number: ");
scanf("%[^4]d", &a);
printf("You entered: %d\n", a);
return 0;
}
As far as I know scansets are meant to be used with strings (which makes the d not act as an integer placeholder specification). One way to write it is to read the input into a string and then parse it:
int main(void)
{
int a;
char b[255];
printf("Enter a number: ");
scanf("%254[^4]", &b);
a = atoi(b);
printf("You entered: %d\n", a);
return 0;
}
I'm keeping the modified code to a minimum, you'd definitely need some extra checks for input sanity.
To clarify: The 254 prefix limits the amount of data that scanf will capture, so as to not exceed the size of the buffer (strings are terminated with an extra null character, so the read length must be smaller than the actual size)1.
The scanset working with only characters.
Here is my sample code. (but, I don't know what you really want.)
#include <stdio.h>
int main(void) {
char buffer[128];
printf("Enter a number: ");
scanf("%[^4]s", buffer);
printf("You entered: %s\n", buffer);
return 0;
}
The result is,
Enter a number: 12345678
You entered: 123
Additionally, if you want integer value, use atoi().
I am trying to understand sscanf behaviour for that I have executed below two program.
void main()
{
char *a = "225.311";
int x = 0, y = 0;
sscanf(a, "%d.3%d", &x, &y);
printf("x is %d, y is %d\n", x, y);
}
output is
x is 255, y is 11
Below program is not working as per my expectation.
void main()
{
char *a = "225.311";
int x = 0, y = 0;
sscanf(a, "%d5.3%d", &x, &y);
printf("x is %d, y is %d\n", x, y);
}
I am expecting 25,11, but the output is
x is 255, y is 0
I am expecting sscanf behaviour should exact same as sprintf in reverse manner. But its not working in my second program. If the format specifed is %d5.3%d, then it has to consider 5 as delimeter. But its not considering and reading all digits for x, and then dot is not matching with 5.3%d so it quits there.
Can somebody please explain this.
That's because the %d conversion specifier means sscanf will keep reading from the buffer pointed to by a till it encounters a non-numeric character in the buffer. This means that %d will consume up till 225 in the string literal "225.311" in your second example.
If the format specifed is %d5.3%d, then it has to consider 5 as
delimeter.
No, that's not true. 5 in the format string means sscanf will match it exactly (after reading an int) in the buffer it reads from. If it fails to match it, then sscanf will return and the value of y is left unchanged. You can check for this by storing the result of sscanf. The return value is equal to the number of input items successfully matched and assigned.
char *a = "225.311";
int x = 0, y = 0;
int retval = sscanf(a, "%d5.3%d", &x, &y);
printf("%d\n", retval); // prints 1
However, note that if the sequence of numeric characters in the buffer is too long to fit into an int, then the behaviour is undefined because of signed integer overflow.
Suggest using a different format and checking the results of sscanf(). Also to distinguish fractions like "0.001" and "0.1", note positions.
const char *a = "225.0311";
int ipart = 0;
unsigned fractionpart;
int n1, n2;
if (sscanf(a, "%d.%n%u%n", &ipart, &n1, &fractionpart, &n2) != 2) {
Handle_BadInput();
}
printf("ipart is %d, fractionpart is %0*u\n", ipart, n2 - n1, fractionpart);
// ipart is 225, fractionpart is 0311
As #ajay discusses, "%d5.3%d" looks for an int, then "5.3" then another int.