C sscanf behaviour - c

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.

Related

where I made the mistake and how to fix it?

#include <stdio.h>
float result(int x, int y);
float result1(int x, int y);
int main()
{
int x,y;
char z;
printf("enter x:\n");
scanf("%d",&x);
printf("enter y:\n");
scanf("%d",&y);
printf("enter z:\n");
scanf("%s",&z);
if (z=='*')
{printf("the result is %.2f",result(x,y));}
else if (z=='/')
{printf("the result is %.2f",result1(x,y));}
else
{printf("there is an error");}
return 0;
}
float result(int x, int y)
{
float r=x*y;
return r;
}
float result1(int x, int y)
{
float r1=x/y;
return r1;
}
```so this is my code. my out put is ---
enter x:
4
enter y:
5
enter z:
*
the result is 0.00
Question was -
take two integer number from user x and y and a character z. the result should be in float.
if z is * then it should be x*y
if z is / then it should be x/y
if z is none of the above then it will return 0
you need to use function .
so it was the question, I know it can be done by switch case but I wanted to try if else.
The problem is this:
scanf("%s",&z);
The format specifier %s is used to read null-terminated strings. The variable z is a single character, it can only hold the empty string (which is only the null-terminator and nothing else).
Any other input will write somewhere in memory and lead to undefined behavior.
If you want to read a single character use the format %c. But be careful, the newline that the Enter key added from previous input will also be read with %c, and you need to ask scanf to skip and ignore it. This is done by adding a leading space to the format string.
So the call should be:
scanf(" %c",&z);

Number of digits printed in C program [duplicate]

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.

Why am I getting a character in output when my input is 5 or more than 5? It is pure mathematical equation. If anything is wrong please tell me

I have compiled this code and it works just fine up to value 4 then it starts returning character instead of integer. I am talking about first equation => x= num*2; Here when I enter num value as 5 the output returns a.
#include <stdio.h>
int main(void)
{
int num;
int x; This right here is an integer still it returns a character
char s[10] = "helloworld";
char f[10];
scanf("%d", &num); //
//printf("%d\n", num);
x = num * 2 ;
printf("%x\n", x);
scanf("%c", &f[10]);
if(s[10] = f[10]){
printf("helloworld");
}
}
please tell me if there is a mistake I am a newbie to coding.
As I see you are learning C language, and after reading your explanation, I feel that you want to print the integer value of variable x.
Kindly replace %x with %d in the print statement of variable x,
and you will be successfully able to print the value.
#include <stdio.h>
int main(void)
{
int num;
int x; // This right here is an integer still it returns a character
char s[10] = "helloworld";
char f[10];
scanf("%d", &num);
x = num * 2 ;
printf("%d\n", x); // %d for integer and %x for hexadecimal values
scanf("%c", &f[10]);
if(s[10] = f[10]){
printf("helloworld");
}
return 0;
}
Finally, do read more about format specifiers in scanf and
printf statements.

What does "%d! = %ld'n" mean in this code?

I'm still a beginner at C, so I'm finding difficulty in understanding "%d! = %ld".
I know that %d and %ld are respectively used for an integer and long, so "! =" is confusing me.
#include<stdio.h>
long factorial(int);
int main() {
int n;
long f;
printf("Enter an non-negative integer: ");
scanf("%d", &n);
if (n < 0)
printf("Negative integers are not allowed.\n");
else {
f = factorial(n);
printf("%d! = %ld\n", n, f); //what does this mean?
}
return 0; }
long factorial(int n) {
if (n == 0)
return 1;
else
return(n * factorial(n-1)); }
This will print:
%d, i.e. the decimal value of int n
! =, i.e. the literal character sequence
%ld, i.e. the decimal value of long f
%d and %ld are the formatting placeholders for int and long int in printf. The exclamation point is just the factorial symbol, as mentioned in the comment.
printf() allows you to print a string with variables inside of it. Let's say you have a variable i, containing an integer, 7.
printf("My variable is %d", i);
Will print
My variable is 7
to the console! That's because %d is how you tell printf(), "Hey, put an integer variable here!". The integer is then supplied as the next argument to the function. In your case, %d represents the integer n, and %ld represents the long integer f. Since f might be really big, we make it a long, which means more bytes are allocated to it internally on your computer. So for example, if we wanted to get the factorial of 5 and print it, we might do the following:
printf("Factorial of %d equals %ld\n", 5, factorial(5))
// this will print "Factorial of 5 is 120" then a newline
Oh, and \n just means print a newline afterwords!
printf("%d! = %ld\n", n, f); //what does this mean?
%d - print an integer as a signed decimal number.
l - specifies that the argument is a long int or unsigned long int as appropriate. %ld then prints a long int or unsigned long int
The printed text will become something like
n! = f
(factorial notation n!)

Scanf function in C with CodeBlocks IDE is buggy?

I'm running some simple code in my CodeBlocks and I wonder why scanf function cannot work with shorts correctly!
The code below is an example. The code takes from the user three int numbers and then prints them again, that simple — but the values printed don't match the values entered.
#include <stdio.h>
int main()
{
short x, y, z;
printf("Please enter three integers! ");
scanf("%d %d %d", &x, &y, &z);
printf("\n num1 = %d , num2 = %d , num3 = %d ", x, y, z);
return 0;
}
The specifier %d is only used for int variables, but in case of short you must use the %hi specifier instead of %d.
So your code must be :
#include <stdio.h>
int main() {
short x , y , z ;
printf("Please Enter three int Numbers ! ");
scanf("%hi %hi %hi",&x,&y,&z);
printf("\n num1 = %hi , num2 = %hi , num3 = %hi ",x,y,z);
return 0;
}
You can find more information about the C data types and their Specifiers here :
https://en.wikipedia.org/wiki/C_data_types
short != int
you pass the pointer to the (usually 2 byte) data, and scanf expects and writes 4 bytes
change short x , y , z ; to int x , y , z ;
as always scanf is not buggy, but the coder is :)
PS Forgot to add. you can also use h format modifier. There is hh as well if you want to scan char sized variables

Resources