printf displays a different value - c

I've got a variable i that is initialized to 1, when I want to display it, it displays 6421788 instead of 1.
int i = 1;
printf("WELCOME: OUR AVAILABLE TRIPS:\n");//displaying trips
while(fgets(trip,sizeof(trip),StrdFile) != NULL)
{
printf("%i.",&i);//the problem
printf("%s\n",trip);
i++;
}
This is the part of the code that must be the problem. The display need to be :
1.\*info*
2.\*info*
but what I get is
6421788.\*info*
6421788.\*info*
also, I checked the value of i in the debugger and it's correct.

You're printing the address of i (kinda). Replace
printf("%i.",&i); // Address of `i`
with
printf("%i.",i); // Value of `i`
Enable and heed your compiler's warnings! With gcc, I use -Wall -Wextra -pedantic; it would have caught this error.
a.c:10:18: warning: format ‘%i’ expects argument of type ‘int’,
but argument 2 has type ‘int *’ [-Wformat=]
printf("%i.",&i);//the problem
~^ ~~
%ls

You are actually printing the number of the memory address which is reserved for your i variable .
Getting this address is done by adding the sign & before the variable name.
printf("%i",&i);
Will print the address of memory address reserved for your var i
printf("%i",i);
Will print the value in your var i .
Take a look here : https://documentation.help/C-Cpp-Reference/printf.html

Related

Why did this code run still work,with '&' or without '&'?

I am a new learner for c.
And I can't see what on earth this difference is.
Thank you for your help!
#include<stdio.h>
int main(void)
{
char a[9];
scanf("%s",&a);//scanf("%s",a)
printf("%s",&a);//printf("%s",a) they all can run correctly!
for(int i=0;i<9;i++)
{
printf("%c;",a[i]);
}
return 0;
}
With &, you are invoking undefined behavior for type mismatch: %s expect char*, but &a here has type char(*)[9] (a pointer to 9-elemnent character array).
In typical environment, pointers are implemented as simple memory addresses.
Despite of type mismatch, the address of the array &a and its first element a will be the same (same size and same value), so there are high chance to work well.
Allow a little analogy
Imagine you live in a (semi-)transparent world and you have a few differently colored laser pointers.
You use red lasers to point at people, blue lasers to point at planes, yellow lasers to point at mobile phones, ..., ...
It's illegal to mismatch pointers and objects (undefined behaviour in C slang), so no yellow lasers on planes, no blue lasers on people, ...
Now imagine you are using a yellow laser to point to a mobile phone of someone travelling in a plane, and you ask a color-blind friend (the printf()) what plane the pointer points to. Your friend does not care about the color and, wrongly, says it's whatever plane the yellow laser shines on.
But the responsible person for the error is you. You tricked your friend!
Don't lie to the compiler
regarding:
#include<stdio.h>
int main(void)
{
char a[9];
scanf("%s",&a);//scanf("%s",a)
printf("%s",&a);//printf("%s",a) they all can run correctly!
for(int i=0;i<9;i++)
{
printf("%c;",a[i]);
}
return 0;
}
When compiling, always enable the warnings, then fix those warnings. ( for gcc, at a minimum use: -Wall -Wextra -Wconversion -pedantic -std=gnu11 ) Note: other compilers use different options to produce the same results.
The posted code results in three(3) warning messages from the compiler
gcc -O1 -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled2.c"
untitled2.c: In function ‘main’:
untitled2.c:5:13: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[9]’ [-Wformat=]
scanf("%s",&a);//scanf("%s",a)
~^ ~~
untitled2.c:6:14: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[9]’ [-Wformat=]
printf("%s",&a);//printf("%s",a) they all can run correctly!
~^ ~~
untitled2.c:5:5: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%s",&a);//scanf("%s",a)
^~~~~~~~~~~~~~
Compilation finished successfully.
The final statement: "Compilation finished successfully.", when there are warning messages, only means the compiler produced some 'work around' for the problems, That does not mean the compiler produced the code that you wanted.
regarding:
for(int i=0;i<9;i++)
{
printf("%c;",a[i]);
}
if the input from the user was less than 8 bytes, then some trash/garbage bytes will be output.
Suggest:
for( int i=0; a[i]; i++ ) // stops on NUL byte
{
printf("%c;",a[i]);
}
so only the user input and not the uninitialized bytes be output.
Even better, since the call to scanf() with %s will have NUL terminated the input is to use the single statement:
printf( "%s\n", a );
OT: When calling any of the scanf() family of functions, always check the returned value (not the parameter values) to assure the operation was successful. Note: those functions return the number of successful 'input format conversion' specifiers (or EOF). Suggest: (after syntax corrections and error checking added)
if( scanf("%8s",a) != 1 )
{ // error occurred
fprintf( stderr, "scanf for input data failed\n" );
exit( EXIT_FAILURE );
}

I wanted to know about the working of "printf" function in c. For example for the print statements used in below code the outputs are different why?

how come the pointer gets printed even with %d
int main()
{
int s=5 ,t ,**p ,*n;
n=&s;
p=&n;
printf("%d",n);
printf("\n%p",*p);
return 0;
}
//answer for first print statement is purely integers
//answer for second one is hexadecimal
This is undefined behavor. You must match the type required by the format specifier to the type of the value passed.
In a comment you made it clear that you wanted to know "why it didn't show any kind of warning or anything".
printf is an example -- the best-known example -- of a variadic or "varargs" function. It does not accept one, fixed list of arguments with an exact number of predefined types. Every time you call printf, you call it with a different number of arguments, and the only way to determine how many arguments and what types they should be is to go through the format string looking for the % signs.
The printf function itself knows how to do this. At run time, when you call it, it goes through the format string looking for % signs, and each time it finds one, it looks at the following letter to determine what type of argument it should fetch next. But at run time, there's no mechanism to double-check what type of argument has actually been passed -- printf just blindly fetches a value (typically from the stack) that's assumed to be of the correct type, and prints it out assuming it had the correct type.
But that was at run time. The only way you could get a warning or error message at compile time would be for the compiler to go through the format string looking for % signs, and match them up with the actual arguments it can see you're passing.
Once upon a time, that wasn't a reasonable thing for a compiler to do. But times have changed, and today this is actually something that a good compiler does do! Here's what I got when I compiled your code using clang on my Mac:
warning: format specifies type 'int' but the argument has type 'int *'
And here's what I got when I compiled it with gcc, using the -Wall option:
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’
warning: unused variable ‘t’
So, the bottom line is: use a modern compiler (and remember to request warnings), and it should tell you about problems like these.
P.S. In a comment I said, "%p is for pointers, but you gave it an int." But I misread your code. Your first printf call uses %d, and passes n, but n is int * which is a pointer, so that's wrong.
Your second printf call uses %p, and passes *p. In your code, p is an int **, a pointer to pointer to int, so *p is a pointer-to-int, and that call is therefore (mostly) correct.

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

GCC: why a -Wformat warning for this fprintf?

We cleaned up a large number of warnings. In several cases, we replaced %s with %d. Everything seemed OK until we realized that the generated code wouldn't compile - strings had been replaced by numbers.
NOTE: I had the wrong revision checked out when I did the copy&paste. The fprintf string has been edited!
GCC output
fedex_plus/classes.c:2425:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat]
lines 2424 and 2425:
fprintf(file, "\n//\t%s_ptr create_TIE();\n\tIDL_Application_instance_ptr create_TIE();\n",
ENTITYget_CORBAname(entity));
function ENTITYget_CORBAname:
const char *
ENTITYget_CORBAname (Entity ent)
{
static char newname [BUFSIZ];
strcpy( newname, ENTITYget_name(ent) );
newname[0] = ToUpper (newname [0]);
return newname;
}
My bet is that no declaration of ENTITYget_CORBAname is available at the fprintf spot. Should this be the case, it defaults to the implicit signature:
int ENTITYget_CORBAname(...);
hence the warning about the result type being an int.
Check your code with -Wimplicit (implied by -Wall), or try to put
const char *ENTITYget_CORBAname (Entity ent);
before the fprintf line and check if the warning disappears. If it does, then you're likely missing a header.
If you want to print a pointer value, use %p, if you want to print the string returned from the function, use %s. Don't use %d in any of this cases. See here.
I assume that ENTITY_GETCorbaName() returns a string, so if you want to print that, use %s. If you want to print it as pointer, use %p.
use %s in your printf to print that string or use %p in your printf to show pointer value you can also use %lld to prints its value

Resources