I am trying to take two variables as input using this code snippet:-
unsigned int i;
unsigned long int j;
scanf("%u",i);
scanf("%lu",j);
But this give rise to the following warnings :-
warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 2 has type ‘unsigned int’ [-Wformat]
warning: format ‘%lu’ expects argument of type ‘long unsigned int *’, but argument 2 has type ‘long unsigned int’ [-Wformat]
Can anyone explain to me whats happening here?
You need to add a leading &, as scanf takes pointers to the output parameters. Otherwise, it can not write to them.
scanf("%lu", &i);
Related
I have the following code:
#include<stdio.h>
int main()
{
printf("The 'int' datatype is \t\t %lu bytes\n", sizeof(int));
printf("The 'unsigned int' data type is\t %lu bytes\n", sizeof(unsigned int));
printf("The 'short int' data type is\t %lu bytes\n", sizeof(short int));
printf("The 'long int' data type is\t %lu bytes\n", sizeof(long int));
printf("The 'long long int' data type is %lu bytes\n", sizeof(long long int));
printf("The 'float' data type is\t %lu bytes\n", sizeof(float));
printf("The 'char' data type is\t\t %lu bytes\n", sizeof(char));
}
Which outputs:
The 'int' datatype is 4 bytes
The 'unsigned int' data type is 4 bytes
The 'short int' data type is 2 bytes
The 'long int' data type is 8 bytes
The 'long long int' data type is 8 bytes
The 'float' data type is 4 bytes
The 'char' data type is 1 bytes
But that's just the thing, the compiler requires that I use %lu(long unsigned int) rather than %d(int), as I would have expected. After all, we are just talking about single digit numbers here, aren't we? So why do I get the following error when using %d instead of %lu? Has it something to do with me being on a 64bit system(Ubuntu 14.10)?
helloworld.c: In function ‘main’:
helloworld.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("The 'int' datatype is \t\t %d bytes\n", sizeof(int));
^
helloworld.c:6:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("The 'unsigned int' data type is\t %d bytes\n", sizeof(unsigned int));
^
helloworld.c:7:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("The 'short int' data type is\t %d bytes\n", sizeof(short int));
^
helloworld.c:8:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("The 'long int' data type is\t %d bytes\n", sizeof(long int));
^
helloworld.c:9:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("The 'long long int' data type is %d bytes\n", sizeof(long long int));
^
helloworld.c:10:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("The 'float' data type is\t %d bytes\n", sizeof(float));
^
helloworld.c:11:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("The 'char' data type is\t\t %d bytes\n", sizeof(char));
^
Compilation finished successfully.
You're trying to print the return value of sizeof operator, which is usually of type size_t.
It appears, in your case, size_t is a typedef of long unsigned int, so it demands it's compatible format specifier %lu to be used. The returned value here does not matter, your problem is with the type mismatch.
Note: To have a portable code, it's safe to use %zu, on compilers based on C99 and forward standards.
In C the type of a sizeof expression is size_t.
The printf specifier to use is %zu. Example:
printf("The 'int' datatype is \t\t %zu bytes\n", sizeof(int));
It has been possible to use this since the 1999 version of the C standard.
Technically, you have undefined behaviour due to mismatched format and data types.
You should use %zu for the type associated with sizeof (which is size_t).
For example:
printf("The 'int' datatype is \t\t %zu bytes\n", sizeof(int));
This is particularly important if you intend to target both 32 and 64 bit platforms.
Reference: http://en.cppreference.com/w/c/io/fprintf
I want to remove warning without change data-type to char.
#include<stdio.h>
#include<stdlib.h>
main()
{
unsigned char ch;
printf("Hello This is Problematic\n");
scanf("%d",&ch);
printf("1\n");
}
This generates the warning
test.c:7:2: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘unsigned char *’ [-Wformat=] scanf("%d",&ch);
Actually,
scanf("%d",&ch);
leaves your program with undefined behavior as the supplied argument is not the correct type for the conversion specifier. You need to write
scanf("%hhu",&ch);
Quoting C11, chapter §7.21.6.2
hh
Specifies that a following d, i, o, u, x, X, or n conversion specifier applies
to an argument with type pointer to signed char or unsigned char.
Why is this considered illegal in C ?
#include <stdio.h>
int main()
{
int integer;
char character;
float floatingPoint;
scanf(" %d %c %f", integer, character, floatingPoint);
return 0;
}
The above code produces the following error message under cc compiler.
cc Chapter2ex1.c
Chapter2ex1.c: In function ‘main’:
Chapter2ex1.c:8:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
scanf(" %d%c%f", integer, character, floatingPoint);
^
Chapter2ex1.c:8:5: warning: format ‘%c’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
Chapter2ex1.c:8:5: warning: format ‘%f’ expects argument of type ‘float *’, but argument 4 has type ‘double’ [-Wformat=]
You need to write
// v---------v-----------v-- addresses taken here
scanf(" %d %c %f", &integer, &character, &floatingPoint);
scanf needs to know the places where it should write the values it reads, not the values that currently reside there.
I have absolutely no idea why it returns 2 for a=2 and b=2..
Any ideas?
#include <stdlib.h>
int main()
{
double a,b,c;
printf("a=");
scanf("%d", &a);
printf("b=");
scanf("%d", &b);
printf("c=");
scanf("%d", &c);
printf("x=%d", a+b);
return 0;
}
The specifier "%d" expects an integer and you are passing the address of a double. Using the wrong specifiers in scanf leads to undefined behavior.
Also, using the wrong specifier in printf is the same thing. Because printf takes a variable number of arguments a + b which is a double can't be converted to an integer.
%d is for reading integers, use %f or %lf for float/double.
printf should use something like %f instead of %d. The same for scanf.
If you want to accept a float input, use scanf (and printf) with the %lf formatting character, not %d (which is for integers).
The behavior of your current program is undefined, since the scanf calls are writing an integer to a float variable. Also, you're missing include <stdio.h> at the top of your program. To catch errors like these, turn on the warnings in your C compiler:
$ gcc so-scanf.c -Wall
so-scanf.c: In function ‘main’:
so-scanf.c:6:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
so-scanf.c:6:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
so-scanf.c:7:5: warning: implicit declaration of function ‘scanf’ [-Wimplicit-function-declaration]
so-scanf.c:7:5: warning: incompatible implicit declaration of built-in function ‘scanf’ [enabled by default]
so-scanf.c:7:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘double *’ [-Wformat]
so-scanf.c:9:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘double *’ [-Wformat]
so-scanf.c:11:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘double *’ [-Wformat]
so-scanf.c:13:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat]
ram#ram:~/Desktop$ cc sample.c
sample.c: In function ‘main’:
sample.c:7: warning: format ‘%o’ expects type ‘unsigned int’, but argument 2 has type ‘long int’
Because they are specified as taking an unsigned int.
(No, really.)