I executed the following code.
#include <stdio.h>
int main()
{char *a="awake";
printf("%s\n", *(a+1));
return 0; // expected out_put to be wake
}
You're dereferencing the pointer, which makes it a char but trying to output a string. Change your print statement to printf("%s\n", a+1);
*(a+1) is the same as a[1] which is a char, not the char * that printf expects for the %s.
EDIT: clarification: printf needs an address for the %s specifier, a+1 is such an address (namely the address of the second character in the string), but *(a+1) then gives the value at that address. Which is just a character and in all likelyhood not a valid memory location for printf to read.
You don't want to defrefeence the char *:
printf("%s\n", (a+1));
does what you want.
Related
probably a dumb question but how do you access a specific character in a char pointer?
I've tried following...
char *pointer = "Hello";
printf("%s", pointer); // prints "Hello"
printf("%s", &pointer[0]); // also prints "Hello"
But what I want is printf(???) => "H". A single character. Or the "e". How is that possible?
pointer is a pointer to char, also called a char *.
After char *pointer = "Hello";, pointer points to the “H”.
When printf is given %s, it takes a char * and prints all the characters it finds starting at that location, until a null character is seen.
To tell printf to print a single character, pass it the actual character value (not a pointer) and use %c:
printf("%c", *pointer);
or:
printf("%c", pointer[0]);
or, for the “e” instead of the “H”:
printf("%c", pointer[1]);
char* pointer = "Hello";
Creates a pointer and assigns it to the base address of "Hello".
pointer and &pointer[0] are the same thing.
pointer[n] takes the address of "Hello" and offsets it by the number 'n', be sure not to index of the end of the address or you will read rubbish.
So:
pointer[0] = 'H'
pointer[1] = 'e'
pointer[2] = 'l'
pointer[3] = 'l'
pointer[4] = 'o'
pointer[5] = 0
You want to access the char of char* simply use [] operator, just like arrays.
char *pointer = "Hello";
printf("%s", pointer); // ok
printf("%s", &pointer[0]); // wrong way of accessing specific element (it is same as the base address.., thus %s prints the whole thing)
Instead you're accessing the address of the first element of char* or string literal.. why!
printf("%c", pointer[0]); // use this one
Just like arrays, access the required element.
However, to get it better, notice here:
#include <stdio.h>
int main() {
char *pointer = "Hello";
printf("%s\n\n", pointer); // ok
printf("%c", pointer[0]);
printf("%p == %p\n", (void *)&pointer[0],(void *)pointer);
// cast to void * to avoid undefined behavior
// pointed out by #ex nihilo
printf("%p", pointer+1);
return 0;
}
Output:
Hello
H0x55da21577004 == 0x55da21577004
0x55da21577005
as you can see, the pointer holds the address of the first element which is: &pointer[0] thus you get the same output.
this was the code snippet asked for me in a interview and pls explain me what is the use of &.
#include<stdio.h>
int main()
{
char *str="INCLUDEHELP";
printf("%s",*&*str);
}
The &* is an empty operation. The &*str (or like &*&*&*&*&*&*&*&*&*str or any number of &*) is equivalent to just str. See C11 note102. We can omit it.
char *str="INCLUDEHELP";
printf("%s", *str);
This code with %s is invalid. The %s expects zero terminated char array. The *str is a char with the value of 'I', a character. The program on linux-like systems will most probably receive a segmentation fault signal, because 'I' will be an invalid address of a zero terminated character array.
If it were:
char *str="INCLUDEHELP";
printf("%c", *str);
or:
#include<stdio.h>
int main()
{
char *str="INCLUDEHELP";
printf("%c",*&*str);
}
, then the program would print a single character I on it's stdout.
The output is most probably the segfault.as it is the Undefined Behaviour. The &*... from the right mean. Dereference the pointer, get the address of the dereferenced char, and dereference this address again passing the char instead of the pointer to printf.
So I tried this code
#include <stdio.h>
int main(void)
{
char string[] = "hello world";
char *my_ptr = string;
*my_ptr='Y';
printf("the first char of string is %c", *my_ptr);
}
OUTPUT_1 :-
the first char of string is Y
Now if I want to print the complete scentence in the string ("Yello world"). For that I changed 7th line to :-
printf("the whole string is %s", *my_ptr);
OUTPUT_2:-
Segmentation fault (core dumped)
But if I try changing it to this :-
printf("the whole string is %s", my_ptr);
OUTPUT_3 :-
the whole string is Yello world
Could someone please explain me why are the second case is failing ? AND
Why the third case prints correct ?
From my understanding *my_ptr (as well as my_ptr both) have the address of the first location, so why does the first one fail in printing a complete string , whereas the second one does well. Im a beginner so it would help if you could detail the reason behind such a behaviour in these cases.
my_ptr is of type char * it's a pointer on the first char of the string.
*my_ptr is of type char it's a character.
printf format string option %s takes a char *, it will loop over each character until it finds a string delimiter (0) :
First, *my_ptr, being Y
Then *(my_ptr + 1), being h
And so on...
When using printf with *my_ptr, The content of *my_ptr will be passed to printf as if it was a string pointer. Its value is 'Y' which is 89 in ascii.
printf will try to access the pointer at address 89 thinking it's a valid string pointer, but this address is most likely not readable and the kernel will kill the program trying to access memory it doesn't have access to.
This will work:
#include <stdio.h>
int main(void)
{
char string[] = "hello world";
char *my_ptr = string;
*my_ptr='Y';
printf("the first char of string is %c", *my_ptr);
printf("the whole string is %s", my_ptr);
}
my_ptr is a pointer to the entire string. *my_ptr is the value of the char at the beginning of the string.
printf("%s", char*)
printf("%c", char)
In the statement below:
printf("the whole string is %s", *my_ptr);
it will read the content from the address of *my_ptr. That produces Segmentation fault (core dumped) While in below:
printf("the whole string is %s", my_ptr);
The string will be read from the base address of string[ ]. To read the string you have to pass the base address from where character should be started to read untill '\0' character is found.
The reasaon is in C, %s is used for printing the string but u uses that to print the char which results in Core dump.
And in C, it is enough to give the base address to print the whole contents, no need to for using *addr.
If u want to access a particular character u can do so by *(a+0) for printing 1st char and *(a+1) for printin 2nd character and so on.
This:
printf("the whole string is %s", *my_ptr);
dereferences the pointer, so it passes a value of type char to printf(), which will then interpret it (due to the %s formatting specifier) as const char *, i.e. as a pointer to read-only character data. The value of a pointer is an address of a location in memory where some data is stored.
This will make printf() start reading characters from some very low address, where your program is not likely to be allowed to read. Thus the segmentation fault.
I want to know why is it that when i call readF() and have it return the buffer pointer and i print the buffer in main() it prints the actual data and not the memory address? I am returning the address and not the actual data correct? In my main i have a pointer that points to what gets returned, which is just what the buffer pointer in readF() points to.
char *readF(){
char *buffer=NULL;
//allocate memory to contain the string plus null terminator
buffer=malloc((sizeof(char)*4)+1);
//fill memory with string Hello plus terminator
return buffer;
}
int main(int argc, char **argv){
char *buffer;
buffer=readF();
printf("%s", buffer);
return 0;
}
You print the actual data inside the buffer because you use the %s format specified in your printf statement. This tells printf to assume the pointer it receives, buffer in this case for the first specifier, is a pointer to a NULL-terminated character string, so it prints the string.
If you want to print the address use the %p format specifier
You're correct when you say the readF function is returning the memory address. It returns the memory address of the first byte of the buffer, ie a pointer to the buffer you allocate.
Note: at the end of your function you should really free(buffer) too :)
To print the address you need %p specifier.
Change
printf("%s", buffer);
to
printf("%p", (void *)buffer);
This one is probably very simple, but I can't seem to get it working.
I have this very simple snippet of code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char buf[100];
char *p = buf;
strcpy(p, "Test string");
printf("%s\n", *p);
}
Which causes a segmentation fault when I run it. GDB outputs:
Program received signal SIGSEGV, Segmentation fault.
0xb76af3b3 in strlen () from /lib/i686/cmov/libc.so.6
But I still don't get it.
Comments would be appreciated, thanks.
When you write
printf("%s\n", *p);
the *p will be the value at p[0] which is a character. The printf however is looking for an array of chars, thus causing it to segfault. Remember that in C, strings are just arrays of characters, and arrays are effectively pointers to the first element, this is why you don't need to dereference.
To fix this remove the * to get:
printf("%s\n", p);
You're passing a character to printf; you should be passing the pointer.
char buf[100];
char *p = buf;
strcpy(p, "Test string");
printf("%s\n", p); // p, not *p
Use this:
printf("%s\n", p);
use "p" instead of "*p"
Replace
printf("%s\n", *p);
with
printf("%s\n", p);
When you use %s, printf expects you to pass a char*. You are passing a char instead.
just pass the string(the pointer):
printf("%s\n", p);
If you want to print the first char, then:
printf("%c\n", *p);
%s causes printf() to dereference *p. Suppose the string was "Test string".
Then on my Solaris sparc box: (in a test program) p would be "aimed at" the address 0x54657374. The probability of that particular address being part of your process space is next to zero.
That is what caused the SIGSEGV signal (segfault).