I had written this c program for study purpose and I have found that
printf("%s",a); works but printf("%s",*a); does not works.
I had defined a like this char *a[]="how are you";
why *ais not pointing towards the string?
I am getting this error
test2.c: In function ‘main’:
test2.c:7:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("%s \n",*a);
~^ ~~
%d
It is undefined behaviour because of %s printf interprets *a as an address, but it's actually not an address and if you treat it as address it points to some location that is read protected for your program. So,may be you get segmentation fault.
Related
Code:
printf( "%s", __builtin_return_address(0));
Warning :
format '%s' expects type 'char *', but argument 2 has type 'void
Side Notes I have been experimenting with some register keywords.. Perhaps the command above would have provided some info if it had worked.
According to gcc.gnu.org, syntax of function:
void * __builtin_return_address (unsigned int level)
function return the void*. So, use %p format specifier instead of %s.
If you want to print the address you need the appropriate specifier,
printf("%p\n", __builtin_return_address(0));
should work.
int main()
{
printf("%c", "\n");
return 0;
}
Here according to type specifier a character is required. But we are passing it const char *. I was hoping that it would give me a warning message in code blocks GNU GCC compiler but it is not giving me any warning and printing the $ character.
why it is not giving any type of warning?
You need to enable that warning.
Compiling your code as test.cpp and adding #include <stdio.h> for printf with the correct warning flag under gcc 4.7.2:
$ gcc -c -Wformat test.cpp
test.cpp: In function 'int main()':
test.cpp:5:18: warning: format '%c' expects argument of type 'int', but argument 2 has type 'const char*' [-Wformat]
With printf() if there is a type mismatch then it leads to undefined behavior.
The format specifier should match with the type which you want to print.
Further the number of arguments should match with the number of format specifiers violating which will also leads to undefined behavior.
Just add -Wall while compiling your code you will get the below error:
warning: format %c expects type int, but argument 2 has type char *
You could see that the code also works with %d, %x, %u format specifiers.
Why it works without any warnings ?
Because you don't have warnings enabled in your CodeBlocks.
Go to settings -> compiler and check
Enable All Common Compiler Warnings [-Wall]
And now you get:
In function 'int main()':
warning: format '%c' expects argument of type 'int', but argument 2 has type 'const char*' [-Wformat=]|
Why it even works ?
With %c, $ is the output in CodeBlocks, X is the output in Visual Studio . So, that sounds like undefined behavior.
Wrong format specifiers in scanf (or) printf
Anyways if you want the first char this way only you could do this:
#include <stdio.h>
int main()
{
printf("%c", *"Hello\n"); // Not asked in Question but still :)
return 0;
}
It prints H by dereferencing the const pointer.
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'm creating a program using C, and I have this line in my code :
scanf("%s", &path);
When I compile the source file, I get this warning :
main.c:84:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[64]’ [-Wformat]
And this is the declaration for the path variable :
char path[64];
Why I'm seeing this error? And how can I solve it ?
An array is already a pointer-like object (as dreamlax points out). You don't need the & operator, since declaring
char path[64];
is equivalent to setting path to a pointer to a 64-byte region of memory.
The %s format specifier requires you to supply a char *, which is a pointer to char. You are passing &path, which is a pointer to an array. You can just pass path by itself, which will evaluate to a pointer to the first element of the array (the same as &path[0]).
try this scanf("%s", path); instead because I think path is an array and a pointer to an array is the array name itself ( array == &array )
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]