When I print a memory address with printf %p I get address in hexdecimal - something like 0x7ffee35f5498. I am wondering why the printf return value is 16 and not the actual length of string, in this case 14?
#include <stdio.h>
int main(void)
{
char *s = "Hello World!";
int x;
x = printf("%p\n", (void*)&s);
printf("%d\n", x);
return (0);
}
output:
0x7ffeea6a3790
16
Address has 14 char but the function returned 16.
Documentation say's:
printf() : It returns total number of Characters Printed, Or negative
value if an output error or an encoding error. ...
You're not just printing the address but also a newline after it. On Linux / MacOS systems a newline is one character (0xA) while on Windows systems it is two characters (0xD 0xA).
From your comments, you say you got 15 as your output and that you're on MacOS. So that's 14 for the printed address plus 1 for the newline which is the expected result.
Related
The output of the above C Language code is Rs.10.008 but why ?????
#include<stdio.h>
int main(){
unsigned i = 10;
i = printf("Rs.%d.00",i);
printf("%d",i);
return 0;
}
This statement:
i = printf("Rs.%d.00",i)
prints Rs.10.00 and returns 8 to indicate the number of characters printed. Notice that you are assigning the return value of printf to i.
Hence, the subsequent printf statement:
printf("%d",i);
Will now print 8 instead of 10. The first printf statement didn't specify an end-of-line char (\n), so it just concatenates the 8 onto the same line.
Your code has undefined behavior as you use %d for printing unsigned int. You need to use %u for unsigned (int) and %d for (signed) int.
If that is fixed we have...
For printf the C standard says:
Returns
The printf function returns the number of characters transmitted, or a negative value if
an output or encoding error occurred.
So
int i = 10; // Note unsigned changed to int
i = printf("Rs.%d.00",i);
will print "Rs.10.00" and set i to 8 because "Rs.10.00" is 8 characters long.
Then
printf("%d",i);
will print "8" so that the total output is "Rs.10.008"
printf() return the number of characters that are printed, since your code is printing 8 characters so the value assigned to i after executing first printf is 8, and since new line is not added before second printf its printing the value of i in same line resulting in Rs.10.008
first printf is printing the value of i that is 10
i=printf("Rs.%d.00",i) // it prints Rs.10.00 and assign the value of i=8
I recently encountered with an interview question. I did not understand the behaviour of printf function in this case
#include <stdio.h>
int main() {
int k = printf("String");
printf("%d",k);
}
Expected result : Compilation Error
Output : String6
Why is the output String6?
Here is the prototype for printf:
int printf(const char *format, ...);
We can see that printf returns an int.
The documentation indicates that:
Upon successful return, these functions return the number of
characters printed (excluding the null byte used to end output to
strings).
You asked why the output is "String6". Well:
printf("String");
This first prints String but does not print a newline character. Since String is 6 characters, printf returns 6, which you store in k:
printf("%d",k);
This then prints 6 (on the same line).
Try running this program:
#include <stdio.h>
int main(void)
{
int bytes_printed = printf("%s\n", "String");
// 7 = 1 + 6
printf("printf returned: %d\n", bytes_printed);
return 0;
}
Output:
String
printf returned: 7
the printf() function returns the number of character it printed. Since you set int k = printf("String");, the print function is executing printing out "String" and setting k equal to 6 since "String" is 6 characters long, then your second call to printf prints the value of k which is 6, resulting in the console displaying "String6".
This is perfectly valid C syntax.
I had an interview and I was given this code and asked what is the output for each one of these printf statements.
I have my answers as comments, but I am not sure about the rest.
Can anyone explain the different outputs for statements 1, 3 and 7 and why?
Thank you!
#include <stdio.h>
int main(int argc, const char * argv[]) {
char *s = "12345";
printf("%d\n", s); // 1.Outputs "3999" is this the address of the first pointer?
printf("%d\n", *s); // 2.The decimal value of the first character
printf("%c\n", s); // 3.Outputs "\237" What is this value?
printf("%c\n", *s); // 4.Outputs "1"
printf("%c\n", *(s+1)); // 5.Outputs "2"
printf("%s\n", s); // 6.Outputs "12345"
printf("%s\n", *s); // 7.I get an error, why?
return 0;
}
This call
printf("%d\n", s);
has undefined behavior because an invalid format specifier is used with a pointer.
This call
printf("%d\n", *s);
outputs the internal code (for example ASCII code) of the character '1'.
This call
printf("%c\n", s);
has undefined behavior due to using an invalid format specifier with a pointer.
These calls
printf("%c\n", *s);
printf("%c\n", *(s+1));
are valid. The first one outputs the character '1' and the second one outputs the character '2'.
This call
printf("%s\n", s);
is correct and outputs the string "12345".
This call
printf("%s\n", *s);
is invalid because an invalid format specifier is used with an object of the type char.
This code is undefined behaviour (UB). You are passing a pointer, where the function requires an int value. For example, in a 64-bit architecture, a pointer is 64 bit, and an int is 32 bit. You can be printing a truncated value.
You are passing the first char value (automatically converted to an int by the compiler) and print it in decimal. Probably you got 49 (the ASCII code for '1'. This is legal use, but be careful about surprises, as you can get negative values if your platform char implementation is signed.
You are printing the passed pointer reinterpreted as a char value. Undefined behaviour, as you cannot convert a pointer to a char value.
You are printing the pointed value of s as a char so you get the first character of string "12345" ('1').
You are printing the next to first char pointed to by s, so you get the second character of string ('2').
You are printing the string pointed to by s, so you get the whole string. This is legal and indeed, the common way to print a string.
You are passing the first character of string to be interpreted as a pointer to a null terminated string to be printed (which it isn't). This is undefined behaviour again. You are reinterpreting a char value as a pointer to a null terminated string. A SIGSEGV is common in this case, (but not warranted :) ) The signal is sent when the program tries to access unallocated memory before reaching the supposed null character that terminates the string (but it could find a '\0' in the way and just print rubbish).
The 7'th line is failing because a C style string is expected as an input, and you are placing a character instead.
Take a look at:
What does %s and %d mean in printf in the C language
C style strings guide
I used the following online C compiler in order to run your code,
and here are the results:
1. 4195988 - undefined behaviour (UB), manifesting here as the address
of the char array as you stated (for a 64 bit address you might or
might not get truncation)
2. 49 - ASCII value of '1'
3. � - undefined behaviour, manifesting here as unsupported ASCII value
for a truncation of the address of the array of chars
(placing 32-bit address into a char - assuming a 32-bit system)
4. 1 - obvious
5. 2 - obvious
6. 12345 - obvious
7. Segmentation fault - undefined behaviour, trying to place the first char
of a char array into a string reserved position
(placing char into a string)
Note on point number 3: we can deduce what took place during run-time.
In the specific example provided in the question -
printf("%c\n", s); // 3.Outputs "\237". What is this value?
This is a hardware/compiler/OS related behavior when handling the UB.
Why? Due to the output "\237" -> this implies truncation under the specific hardware system executing this code!
Please see the explanation below (assumption - 32-bit system):
char *s = "12345"; // Declaring a char pointer pointing to a char array
char c = s; // Placement of the pointer into a char - our UB
printf("Pointer to character array: %08x\n", s); // Get the raw bytes
printf("Pointer to character: %08x\n", c); // Get the raw bytes
printf("%c\n", s); // place the pointer as a character
// display is dependent on the ASCII value and the OS
// definitions for 128-255 ASCII values
The outputs:
Pointer to character array: 004006e4 // Classic 32-bit pointer
Pointer to character: ffffffe4 // Truncation to a signed char
// (Note signed MSB padding to 32 bit display)
� // ASCII value E4 = 228 is not displayed properly
The final printf command is equivalent to char c = s; printf("%c\n", c);.
Why? Thanks to truncation.
An additional example with a legitimate ASCII character output:
char *fixedPointer = 0xABCD61; // Declaring a char pointer pointing to a dummy address
char c = fixedPointer; // Placement of the pointer into a char - our UB
printf("Pointer to 32-bit address: %08x\n", fixedPointer); // Get the raw bytes
printf("Pointer to character: %08x\n", c); // Get the raw bytes
printf("%c\n", fixedPointer);
And the actual outputs:
Pointer to 32-bit address: 00abcd61
Pointer to character: 00000061
a
Update:
The original code looked a lot like this:
// printf(printf(););
#include <string>
int main()
{
printf(printf("Hello, WORLD!"););
}
However, in the original post, printf("Hello, WORLD!") was assigned to a variable, x.
Intended questions:
How do I call the return value of a function within a function? As a beginner, learning to reference a string variable using %s, I wondered how to reference a the return value of a function (for example, if the return value were a string, would I still use %s).
What does "called to print" mean? I think a simplistic explanation is: the string is put into memory and assigned an address, and the class definition tells the compiler to look up the location in memory based on the class's input-argument definition; so, the address in memory is called to print by the compiler.
Is the first argument of printf() also the return value of printf() such that x == "Hello, World!" is true in x = printf("Hello, World!")?
Original post:
I'm looking at http://www.cplusplus.com/reference/cstdio/printf/
it says: int printf ( const char * format, ... );, but it doesn't define .... So, I don't know what ... is referencing. I wrongly assumed that meant ( const char * format, const char * format, const char * format, ~. But in fact, I can't decipher the meaning based on guessing and reading.
Using this program:
#include <stdio.h>
int main(int argc, char ** argv)
{
str x = printf("Hello, World!\n");
printf("x has %d characters.\n", x);
//"x has %d characters.\n" appears first, x appears second.
return 0;
}
We see the result:
Hello, World!
x has 14 characters.
When I expected:
x has 14 characters. //because this appears first.
Hello, World! //because this appear second.
Because x comes after x has 14 characters..
Someone please explain why ./a.out is giving me the results in backwards order (using gcc and shell in Ubuntu); furthermore, eclipse is shown to give the results in this same backward order.
Perhaps another way to rephrase the question would be: where is "Hello, World!\n" being called to print?
Hello, World! appears first because you printed it first.
First (on line 4), you call printf as follows: printf("Hello, World!\n"). It prints Hello, World! and a line feed. You save the value returned by the call (14, the number of characters printed) in x.
Then (on line 5), you call printf as follows: printf("x has %d characters.\n", x). It prints x has 14 characters. and a line feed. The returned value is discarded.
Note that x has no characters; it has a number. Specifically, it has the number returned by the first call to printf, which is the number of characters it printed.
The following gives the output you desire:
const char* msg = "Hello, World!";
size_t len = strlen(msg);
printf("msg has %zu characters.\n", len);
printf("%s\n", msg);
You are trying to get the length of the string with printf but it also print's out the given string while returning printed characters length. It's not what you want.
You can use strlen instead of printf to get the length of a string without printing it to the output.
char *str = "Hello, World!\n";
int x = strlen(str);
printf("x has %d characters.\n", x);
printf(str);
return 0;
When you call printf, it will print whatever string you pass it as an argument.
So, you are getting the prints on console in the same order you placed them in your code.
Update after the edit from OP:
I still don't quite comprehend what you meant by //because this appear second. comment there.
x has 14 characters. //because this appears first.
Hello, World! //because this appear second.
My take of the problem is, What you are trying to do is get an explanation on why Hello World is printed first and then x has 14 characters. is getting printed.
I can't tell this in simplest of the words than, "Because, when the code is getting executed, processor encounters first call to printf() function with a string argument "Hello World\n". So it dumps that on console.
Then comes the second call with printf("x has %d characters.\n", x);, eventually dumping that on the console later."
Obviously, the value of x is 14 because count of chars in string Hello World! is 13+1 (i.e. 14)
Now the confusion:
If you think that you just defined x as printf("Hello World!\n"), then thats a wrong assumption.
With int x = printf("Hello, World!\n"); statement, you, in fact declared an int variable x and initialized (or assigned) it with value returned by printf("Hello World\n");, which is 14.
Consider this little program:
#include <stdio.h>
int foo(int bar)
{
printf("Foo %d\n", bar);
return 42;
}
int main() {
int x = foo(12); // we call the foo function which prints "Foo 12"
// the return value of foo is assigned to x"
printf("Hello World.\n"); // we print "Hello World"
printf("x = %d\n", x); // we print "x = 42"
}
The output is:
Foo 12
Hello World.
x = 42
If you understand this little program, you should understand also the output of your program.
In your program:
#include <stdio.h>
int main(int argc, char ** argv)
{
int x = printf("Hello, World!\n"); // you call printf which prints ("Hello World!")
// and the return value of printf is assigned to x
printf("x has %d characters.\n", x); // then we print "x has 14 characters"
return 0;
}
Hence the output is
Hello, World!
x has 14 characters.
because you called x = printf("Hello, World!\n") first;
the system will do the printf in output and also assign x = 14
therefore you have your second printf.
I'm trying to follow some steps in a book. This is the exact code that's in the book but I'm getting an error message.
Both of the printf statements are the problem:
printf(pointer);
printf(pointer2);
How do I fix this to actually print what's inside the pointer?
#include <stdio.h>
#include <string.h>
int main(void)
{
char str_a[20]; //A 20-element array
char *pointer; //A pointer, meant for a character array
char *pointer2; //And yet another one
strcpy(str_a, "Hello World\n");
pointer = str_a; //Set the first pointer to the start of the array
printf(pointer);
pointer2 = pointer + 2; //Set the second one 2 bytes further in.
printf(pointer2);
strcpy(pointer2, "y you guys\n"); //Copy into that spot.
printf(pointer);
return 0;
}
Try
printf("%s", str_a);
Now, if you want to print the address of the variable itself, you can try:
int a = 5;
printf("%p\n",(void*)&a);
Use
printf("%s", str_a);
It will print your str_a. But keep in mind that every char*-string in C has to be terminated by a \0-character. If it is not terminated, then everything that is in the ram after the string is also printed and accessed.
In the best case this results in a SIGSEGV, and your programm terminates. In the worst case somebody can use this to print for example plaintext password data stored in the RAM right beside the string you tried to print.
Read about "buffer overflow" and "stack overflow".
If you define the string by
const char* str = "Hello World";
then C will automatically add the \0 character for you, and the actual length of the string is 12 Bytes (for 11 Characters).
But if you go by strcpy or by reading it from stdin or from any untrusted source (like network) then you have a security leak.
But just for testing printf("%s", str_a) is just fine.
Other parameters for printf would be:
d or i Signed decimal integer 392
u Unsigned decimal integer 7235
o Unsigned octal 610
x Unsigned hexadecimal integer 7fa
X Unsigned hexadecimal integer (uppercase) 7FA
f Decimal floating point, lowercase 392.65
F Decimal floating point, uppercase 392.65
e Scientific notation (mantissa/exponent), lowercase 3.9265e+2
E Scientific notation (mantissa/exponent), uppercase 3.9265E+2
g Use the shortest representation: %e or %f 392.65
G Use the shortest representation: %E or %F 392.65
a Hexadecimal floating point, lowercase -0xc.90fep-2
A Hexadecimal floating point, uppercase -0XC.90FEP-2
c Character a
s String of characters sample
p Pointer address b8000000
n Nothing printed.
(source http://www.cplusplus.com/reference/cstdio/printf/)
You use these parameters like:
printf("%i: %f and i am a Character: [%a]", 10, 4.4, (char)a);