C programming %d { printf("%d"); } - c

The program is as follows:
#include<stdio.h>
int main()
{
int a[7]={1,2,3,4};
printf("%d%d%d%d%d",(*a),*(&*a),a[*a*0],*a);
return 0;
}
The Output on codepad.org is as follows:
11110
The Output on ideone.com is as follows:
1111-1074526944 where -1074526944 keeps varying every execution
I executed it on my personal gcc output is: 11110 i dont have the latest gcc
In the printf(); statement i am not concerned about the first four %d's because its totally obvious.
its the fifth %d i am concerned about. Why does it give such an output?

It tries to access whatever data happened to be on the stack of the call to printf() at the offset where a supposed "fifth parameter" would be, which your call to the function obviously has not provided.
To get a feel for it, learn how to write variadic functions.
To really understand it, you'd have to learn assembly.
To avoid such programming mistakes, use the -Wall parameter, which would have told you:
$ gcc -Wall main.c
main.c: In function ‘main’:
main.c:5:4: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat]

Related

Unexpected result when parsing argument in main function in C

I have really simple code to understand command line arguments parsing of main in C language:
#include <stdio.h>
int main(int argc, char* argv[]){
for(int i=1; i < argc; i++)
printf("%d\n", argv[i]);
printf("Number of arguments: %d\n", argc);
}
Having compiled and executed in a terminal passing 3 integers (eg. 1, 2, 3), I obtain the following strange result:
1175842993
1175842995
1175842997
Number of arguments: 4
I know that the solution is lying right straightforwardly towards my eyes, but it's been a hour that I cannot actual figure it out! Any hints? Thanks!
Dereference your pointer:
printf("%d\n", *argv[i]);
You may also be a little surprised, as you will get a numerical value represented by the (first) character printed; for instance for 1 it is 49.
In general you can tell your compiler to tell you a bit more by enabling more warnings. For instance gcc -Wall would tell you:
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
printf("%d\n", argv[i]);
Which would actually be a pretty solid hint.
And a side note: if you declare your main as int, you should return one too. ;) (But see EDIT2 for details).
EDIT: I guess I should have mentioned that with the actual output surprise in the second paragraph.
If verbatim reprint of the argument(s) is what you actually wanted. You'd use %s in your formatting string as Jonathan Leffler pointed out in the comment. In that case, you want the argument passed to be pointer to a string again (i.e. you do not use the * dereference operator).
EDIT2: As pointed out by Antti Haapala regarding the closing "Side note".
When using C99 or C11 you do not have to explicitly return (a value) for your main (and we're talking about main) that has been declared to return int. In that case default of 0 will be assumed. You really only need to do that for when adhering to C89 standard or other functions. For sake of simplicity though and/or when not sure what your target compiler configuration is, you won't be wrong being (type) consistent between your declared and actually returned value type. And again. gcc -Wall for example would let you know about that.

Compilation on Terminal gives off pointer warning and strange symbols

I am trying to compile and run a simple C program from my Terminal. This is my code:
#include <stdio.h>
//integers that are 3n, 3n + 1, and 3n + 2
int main(){
int n,i,a,b,c;
scanf("%d", &n);
for (;n>0;n--) {
scanf("%d", &i);
if(n%3==0){a+=1;}
if(n%3==1){b+=1;}
if(n%3==2){c+=1;}
}
printf("%d %d %d", &a,&b,&c);
return 0;
}
After compiling it one time it generates this warning:
warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]
I don't understand why it is generating that warning because I am not assigning any pointer variables. Why is it generating it?
Also, after compiling it a couple of times more my c file is turning into symbols. I don't understand why this is happening.
The name of my file is 73.c and this is how I'm compiling it on Terminal:
gcc 73.c -o 73.c
After that my file in converted to something like this (lines and lines of this):
œ˙Ì˛����Ä��������Ö� ��������H���__PAGEZERO��������������������������������������������������������(��__TEXT����������������������������������������������������__text����������__TEXT����������0�����˝�������0���������������Ä������������__stubs���������__TEXT����������.������������.��������������Ä�����������__stub_helper���__TEXT����������<�����$�������<���������������Ä������������__cstring�������__TEXT����������`������������`�����������������������������__unwind_info���__TEXT����������l�����H�������l������������������������������__eh_frame������__TEXT����������∏�����#�������∏��������������������������������Ë���__DATA��������������������������������������������������__nl_symbol_ptr�__DATA���������������������������������������������������__la_symbol_ptr�__DATA����������������������������������������������������H���__LINKEDIT������� ������������� ������`��������������������"��Ä0���� ����� ������������� �� ���# ��0���������∏ ����� !��#���
I really don't have any idea of what's going on. I've been at it for a long time now, I know it shouldn't be that hard but I really don't know what's wrong. Somebody have any idea of what might be happening?
There are two major things that are wrong here:
You try to print the address of variables a, b and c.
You invoke Undefined Behavior, but not initializing your
counters to 0.
You want to print the integers, so change this:
printf("%d %d %d", &a,&b,&c);
to this:
printf("%d %d %d", a, b, c);
I also added some spaces, but that's just to beautify the code, to make it more readable, it won't affect the execution.
You don't want to print the addresses! That's why you get the warning. Read more here: What is the difference between the * and the & operators in c programming?
As achelper, mentioned, you don't compile your program as you should (but that's not the problem of the code), but it's something you should get used to. I will demonstrate what I did to compile me program (I also like to use -Wall flag, which enables all warnings):
C02QT2UBFVH6-lm:~ gsamaras$ nano main.c
C02QT2UBFVH6-lm:~ gsamaras$ gcc main.c -Wall -o main
main.c:13:22: warning: format specifies type 'int' but the argument has type
'int *' [-Wformat]
printf("%d %d %d", &a,&b,&c);
~~ ^~
main.c:13:25: warning: format specifies type 'int' but the argument has type
'int *' [-Wformat]
printf("%d %d %d", &a,&b,&c);
~~ ^~
main.c:13:28: warning: format specifies type 'int' but the argument has type
'int *' [-Wformat]
printf("%d %d %d", &a,&b,&c);
~~ ^~
main.c:11:16: warning: variable 'c' is uninitialized when used here
[-Wuninitialized]
if(n%3==2){c+=1;}
^
main.c:5:16: note: initialize the variable 'c' to silence this warning
int n,i,a,b,c;
^
= 0
main.c:10:16: warning: variable 'b' is uninitialized when used here
[-Wuninitialized]
if(n%3==1){b+=1;}
^
main.c:5:14: note: initialize the variable 'b' to silence this warning
int n,i,a,b,c;
^
= 0
main.c:9:16: warning: variable 'a' is uninitialized when used here
[-Wuninitialized]
if(n%3==0){a+=1;}
^
main.c:5:12: note: initialize the variable 'a' to silence this warning
int n,i,a,b,c;
^
= 0
6 warnings generated.
C02QT2UBFVH6-lm:~ gsamaras$ ./main
2
1
2
1461300256 1461300252 1461300248C02QT2UBFVH6-lm:~ gsamaras$
In general, when in doubt, treat warnings as errors, so let's debug that code together, it will be fun. Pro-tip: Start from the first warning and resolve it. After that, the next warnings may be related, thus gone without having you really reading them!
After applying my suggestion, all the warnings related with what you described in your question are gone. Only the uninitialized variable ones are left.
That's easy, just initialize your variables to some initial value, like -1, if that makes sense of course.
In your case though, you use a, b and c as counters! So you must initialize them to 0, otherwise you are starting adding your values to garbage values, and that invokes Undefined Behavior!
So do change this:
int n,i,a,b,c;
to this:
int n, i, a = 0, b = 0, c = 0;
Without the initialization of the counters, I am getting, on my machine, now
C02QT2UBFVH6-lm:~ gsamaras$ ./main
2
1
2
1505029184 1 1C02QT2UBFVH6-lm:~ gsamaras$
You see that printf() gives me some garbage, while after initializing my counters to 0, I got:
C02QT2UBFVH6-lm:~ gsamaras$ ./main
2
1
2
0 1 1C02QT2UBFVH6-lm:~ gsamaras$
The points mentioned by gsamaras are correct, you should use :
printf("%d %d %d", a, b, c);
The syntax you were using is used in
scanf (pass address of the variable where the data is need to be filled.)
Also initialize variables while defining.
Regarding compilation:
The name -o specifies the output file generated after compilation thus it is overwriting your source code (i.e., 73.c).
If you omit -o, the default output file is generated as a.out. So for compiling you can use following and run the program as ./a.out:
gcc 73.c
man gcc quotes:
-o file
Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler
file or preprocessed C code.
If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s,
a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.

Why compilation still work when inverting the main function argument position

Why my C program doesn't work when I declare the main function like this (I inverted the arguments position) :
int main(char * argv, int argc){
}
I compiled it without problem but I got errors when I run it.
Thanks.
Due to the incorrect main() signature, this is not a valid C program.
Try enabling compiler warnings. My compiler tells me about the problem:
$ gcc -Wall test.c
test.c:1:5: warning: first argument of 'main' should be 'int' [-Wmain]
test.c:1:5: warning: second argument of 'main' should be 'char **' [-Wmain]
See What are the valid signatures for C's main() function?
Unlike in C++, functions in C are solely identified by their names, not their arguments. E.g. linker will be pretty happy when it sees a 'main' function.
Nevertheless, there are certain assumptions how main() is called by the operating system resp. the runtime environment. When your parameters are wrong, your program will see unexpected values and might crash.
And btw, you probably will see errors or warnings when you enable diagnostics (e.g. '-Wall -W') when building the program.
This is an incorrect main() signature. You may check the main function.
The parameters argc, argument count, and argv, argument vector,1
respectively give the number and values of the program's command-line
arguments. The names of argc and argv may be any valid identifier in
C, but it is common convention to use these names.
Also check What should main() return in C and C++?

C printf printing random number

I am very new to C Programming and have a doubt... I've been asked to find errors in certain segments of C code... and this segment has me a bit confused so would appreciate the help...
int main(void)
{
int myInt = 5;
printf("myInt = %d");
return 0;
}
As far as i understand there is nothing wrong in this code. What i wanna know is why is this statement printing out a random number ??
The output i get is
myInt = 1252057154
Would appreciate the help... Thanks
You should read more about C programming.
And you should enable all warnings and debugging when compiling. With GCC, this means gcc -Wall -Wextra -g (on Linux at least).
When compiling with
gcc -Wall -Wextra -g john.c -o john
I am getting the following warnings:
john.c: In function ‘main’:
john.c:4:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
john.c:4:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
john.c:4:5: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat]
john.c:3:9: warning: unused variable ‘myInt’ [-Wunused-variable]
So the correction is simple:
/* file john.c */
#include <stdio.h>
int main(void)
{
int myInt = 5;
printf("myInt = %d\n", myInt);
return 0;
}
which gets compiled without warnings.
Notice the \n at the end of printf format string. It is important.
Always enable all the warnings the compiler can give you and trust the compiler, so correct your code till no warnings is given.
And learn to use the debugger (e.g. gdb on Linux).
The behavior you observed is undefined behavior; anything could happen with a standard conforming implementation of C (even an explosion).
Happy hacking.
printf (and similarly scanf) works like this:
Let's say you issue a call to printf
printf("%d some text %f %u %hu some more text\n", arg1, arg2, arg3, arg4)
printf goes over the format string and replaces %? with an argument, based on ?
%d some text %f %u %hu some more text
| | | |
arg1 arg2 | arg4
arg3
Now the thing with functions taking variable number of arguments is that, they don't know if the arguments exist, that's why they just take data from a specific part of the stack based on the format string. If you write:
printf("%d %f %u\n");
it reads three non existing data from the stack, most probably get the values stored when calling the function (values that should be hidden from you)
Well, if it's printing something wrong, the problem is in the printf call:
printf("myInt = %d");
Which arguments you're expected to pass?
It should be this:
printf("myInt = %d",myInt);
If you don't include the variable, then it basically pulls a random chunk of memory in. In addition, it might cause more wierd stuff to happen if you do this with a larger chunk of code. Always make sure that you have as many variables from a printf statement as you need, or bad stuff will result.
printf is a function that receives one or more arguments.
In your case it received only one argument (which is legal) but the argument containes %d which tells printf to take the second argument instead of the %d.
printf takes the "second argument" from the stack, and because only one argument was pushed to the stack (the string), it uses the return address as the second argument.
int main(void)
{
int myInt = 5;
printf("myInt = %d",myInt);
return 0;
}
The only change in the code is I added myInt variable in the printf statement if you see at the end.Whenever a variable is assigned some value it can be displayed only by passing it to the printf() function with the corresponding type specifier.Its a rule in C.

Why does atoi() cause a bus error?

#include <stdlib.h>
#include <stdio.h>
main()
{
const char* str_int = "777";
const char* str_float = "333.3";
int i = atoi(str_int);
float f = atof(str_float);
printf("%s %s", i, f);
}
I have tried several bits of example code I‛ve found online, and all of them cause bus errors. Why is this happening?
Your printf is incorrect. Try this instead:
printf("%d %f", i, f);
The problem is that your format specifiers are %s, which expect strings. But you gave it an intand a float. Therefore the result is undefined behavior.
The reason why it's crashing is because printf will try to read the parameters as strings (which are pointers) and deference them as such, but they are invalid pointers.
Here's a reference on printf and its format specifiers:
http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Please take the habit of asking warnings from your compiler. With gcc it is the -Wall option and (on Linux/Debian/Sid gcc 4.6) I'm getting with your example file david.c using the gcc -Wall -g -o david david.ccommand:
david.c:4:1: warning: return type defaults to 'int' [-Wreturn-type]
david.c: In function 'main':
david.c:11:5: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat]
david.c:11:5: warning: format '%s' expects argument of type 'char *', but argument 3 has type 'double' [-Wformat]
david.c:12:1: warning: control reaches end of non-void function [-Wreturn-type]
A newbie should correct his code till the compiler gives no more warnings. There are very very rare cases when leaving a warning is acceptable (it should happen less than once a year for a seasoned C programmer).
It's not, printf is. You're telling printf that you're passing it two strings ("%s"), when in fact you're passing an int and a float. It should be:
printf("%d %f", i, f);
Otherwise it'll treat the two arguments on the stack as strings (ie. char*).
Since two char*s haven't been passed as promised, when it tries to print the values of what it thinks are two strings on the stack, it'll cause undefined behaviour and potentially crash. This is most likely because the pointers it's trying to dereference are invalid and don't in fact point to a valid address.
printf has no way of telling if the arguments you're passing are correct, your compiler warnings however will. Turn up your compiler warnings.
Read here for more about warning options with gcc (if that's what you're using): http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Read here for more about the format specifiers (ie. %s, %d): http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Printf is not correct.Change it to
printf("%d,%f",i,f);
Refer this link to understand the printf syntax clearly:
http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output

Resources