C char pointer get a specific character - c

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.

Related

Weird beahaviour of string pointers

#include <stdio.h>
int main()
{
char*m ;
m="srm";
printf("%d",*m);
return 0;
}
The output is 115. Can someone explain why it gives 115 as output?
*m is the same as m[0], i.e. the first element of the array pointed to by m which is the character 's'.
By using the %d format specifier, you're printing the given argument as an integer. The ASCII value of 's' is 115, which is why you get that value.
If you want to print the string, use the %s format specifier (which expects a char * argument) instead and pass the pointer m.
printf("%s\n", m);
You have a few problems here,
the first one is that you're trying to add three bytes to a char, a char is one byte.
the second problem is that char *m is a pointer to an address and is not a modifiable lvalue. The only time you should use pointers is when you are trying to point to data
example:
char byte = "A"; //WRONG
char byte = 0x61; //OK
char byte = 'A'; //OK
//notice that when setting char byte = "A" you will recieve an error,
//the double quotations is for character arrays where as single quotes,
// are used to identify a char
enter code here
char str[] = "ABCDEF";
char *m = str;
printf("%02x", *m); //you are pointing to str[0]
printf("%02x", *m[1]); //you are pointing to str[1]
printf("%02x", *m[1]); //you are pointing to str[1]
printf("%02x", *(m + 1)); //you are still pointing to str[1]
//m is a pointer to the address in memory calling it like
// *m[1] or *(m + 1) is saying address + one byte
//these examples are the same as calling (more or less)
printf("%02x", str[0]); or
printf("%02x", str[1]);
Pointers and arrays act similarly .Array names are also pointers pointing to the first element of the array.
You have stored "srm" as a character array with m pointing to the first element.
"%d" will give you the ASCII value of the item being pointed by the pointer.
ASCII value of "s" is 115.
if you increment your pointer (m++) then print it's ascii value , output will be ascii value of "r" - 114.
#include <stdio.h>
int main()
{
char *m ;
m="srm";
m++; //pointing to the 2nd element of the array
printf("%d",*m); //output = 114
return 0;
}

Character Pointer in C

Experts I've some doubts in this programme.
#include<stdio.h>
void main() {
char str1[] = "Hello";
char * p = "Hello", * s, * q;
p = "Bye";
printf("%s", p);
s = p;
printf("%s", s);
q = str1;
printf("\n%s", q);
}
Here p,s and q are character pointers. As we know pointers store the address of a variable and suppose if we used p=str1 then it should store the base address of array str1. Then here how p is acting like an array itself which is storing a string? I've not really understood what's character pointer. Is it not really a pointer? Because we are not using & and neither are we getting the address as an output. Please help. Thank you.
You are very much correct here:
As we know pointers store the address of a variable and suppose if we used p=str1 then it should store the base address of array str1.
Your first question:
Then here how p is acting like an array itself which is storing a string?
You can say p is acting like an array but in reality, it is just a pointer which is pointing to the base address of string str1 which is a null-terminated string.
Your second question:
I've not really understood what's character pointer. Is it not really a pointer?
A character pointer is again a pointer like the pointers to other types in C.
But there is catch here. when you do:
char a = 'A';
char *ptr = &a; // ptr points to character 'A'
Here ptr is pointer to a character.
But when you do:
char *str = "Hello";
char *ptr = str; // ptr points to first character of string str
Here ptr is pointer to a string
A point to note here is - pointer to a character is different from the pointer to a string.
In C, strings are defined as an array of characters. The difference between a character array and a string is the string is terminated with a special character ‘\0’.
So,
char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str[] = "Hello";
Both are same but there is a difference in the way they have been initialized.
Wherever in the program, we use str, this will give the base address of string "Hello". Similarly, string literals are also an array of characters with an exception that they can not be changed because the compiler may put them read-only data section.
So, if we have char *ptr = str then
ptr[0] == str[0]
ptr[1] == str[1]
.....
..... and so on
Because,
ptr[0] is *(ptr + 0) which is character at 0th location of string str and can also be written as *ptr and
ptr[1] is *(ptr + 1) which is a character at the 1st location of string str.
When we increment a pointer, it gets incremented in steps of the object size that the pointer points to. Here, ptr is pointer to char so, ptr+1 will give address of next character and *(ptr + 1) give the character at that location. That's why to the user it looks like its acting like an array.
Your third question:
Because we are not using & and neither are we getting the address as an output.
If I am getting it correctly you want to print the base address of the string, the pointer is pointing to.
In order to get the base address of string a pointer is pointing to you need to use %p. Like this:
#include<stdio.h>
int main() {
char str1[] = "Hello";
char * ptr = str1;
printf ("%s\n", str1);
printf ("%s\n", ptr);
printf ("%p\n", ptr);
printf ("%p\n", str1);
printf ("%p\n", &str1[0]);
return 0;
}
Output on my system:
Hello
Hello
0x7fff5e997b46
0x7fff5e997b46
0x7fff5e997b46
Here you can see - ptr, str and &str[0] giving same address.

Explanation regarding character pointer for string

Hi I'm new to programming.
In the following code str is a pointer to a character, so str should contain the address of the character 'h'. Therefore %p should be used to print that address. But I don't understand how %s is used for printing a pointer parameter.
#include<stdio.h>
int main (){
char s[] = "hello";
char *str = s;
int a[] = {1, 2, 3, 4, 5};
int *b = a;
printf("%s\n", str); // I don't understand how this works ?
printf("%c\n", *str); // This statement makes sense
printf("%c\n", *(str + 1)); // This statement also makes sense.
printf("%p\n",str); // This prints the address of the pointer str. This too makes sense.
printf("%d\n",*b); // makes sense, is the same as the second print.
// printf("%d",b); // I don't understand why str pointer works but this gives a compile error
return 0;
}
char s[] = "hello";
Declares an array of zero-terminated characters called s. Its the same as writing
char s[6] = { 'h', 'e', 'l', 'l', 'o', '\0' };
As you can see, the quotation marks are a shorthand.
char *str = s;
This declares str to be a pointer to a character. It then makes str point to the first character in s. In other words, str contains the address of the first character in s.
int a[] = {1, 2, 3, 4, 5};
Declares an array of integers. It initializes them to the values 1-5, inclusive.
int *b = a;
Declares b to be a pointer to an int. It then makes b point to the first int in a.
printf("%s\n", str);
The %s specifier accepts the address of the first character in the string. printf then walks from that address, printing the characters it sees, until it sees the \0 character at the end.
printf("%c\n", *str);
This prints the first character in str. Since str is pointing to a character (the first character in the string), then *str should obtain the character being pointed at (the first character in the string).
printf("%c\n", *(str + 1));
This prints the second character in str. This is the long way of writing str[1]. The logic behind this is pointer arithmetic. If str is the address of a character, then str + 1 is the address of the next character in the array. Since (str + 1) is an address, it may be dereferenced. Thus, the * obtains the character 1 character past the first character of the array.
printf("%p\n",str);
The %p specifier expects a pointer, just like %s would, but it does something else. Instead of printing the contents of a string, it simply prints the address the pointer is containing, in hex.
printf("%d\n",*b);
This prints the first int in the array pointed to by b. This is equivalent to writing b[0].
printf("%d",b);
b is an int *, not an int, which is what %d expects. If you were trying to print the address of the first element of the array, the specifier would be %p, not %d. Also, this line should not generate a compiler error. Instead, it should have been a runtime undefined behavior, since the compiler does not know what a printf format string is.

usage pointer arithmetic confusion

I'm little bit confused about usage pointer arithmetic. I ask confusing question in the code as comments. I think when it is increased, the other also must be increased. Can someone explain?
#include <stdio.h>
int main()
{
const char *str = "abcde";
const char *temp = str; // str is pointer to address of first element of temp isn't it?
printf("%d\n", temp - str); // zero okey
printf("temp str\n");
printf("%d %d\n", temp, str); // shows same adresses
str++; // hard to understand a point is here
printf("%d %d\n", temp, str); // why weren't also temp increased?
temp++;
printf("%d %d\n", temp, str); // why weren't also str increased?
temp++;
printf("%d %d\n", temp, str); // why weren't also str increased?
return 0;
}
temp and str both are different pointer variables. Modifying any of them will not cause the modification of other but modifying the data they point to will have effect.
You should keep in mind that in your case you can modify str and temp but can't modify the string literal they points to because string literals are not modifiable.
Also note that for pointer data type %p is used as format specifier in printf to print the address they point to.
temp won't be increased by increasing str just as b won't be increased by increasing a in int a=0, b=0;. They are independent variables.
str is pointer to address of first element of "abcde" and it won't have any relationships with temp because it is defined before temp is defined.
By the way, do not try to print pointers with %d. This is undefined behavior because the types don't match.
#include <stdio.h>
int main(void)
{
const char *str = "abcde";
const char *temp = str; // str is pointer to address of first element of temp isn't it?
printf("%ld\n", (long)(temp - str)); // zero okey
printf("temp str\n");
printf("%p %p\n", (void*)temp, (void*)str); // shows same adresses
str++; // hard to understand a point is here
printf("%p %p\n", (void*)temp, (void*)str); // why weren't also temp increased?
temp++;
printf("%p %p\n", (void*)temp, (void*)str); // why weren't also str increased?
temp++;
printf("%p %p\n", (void*)temp, (void*)str); // why weren't also str increased?
return 0;
}
In your code, temp and str are themselves two different variable, however, the data they point to, are same.
If you modify the content pointed by either of them, you can see the change reflected through other.
Also, FWIW, for printing address, change
printf("%d %d\n", temp, str);
to
printf("%p %p\n", (void *) temp, (void *)str);
otherwise, by violating the requirement of appropriate type of parameters to the format specifier, you'll invoke undefined behavior.
const char *temp = str;
means temp pointer takes value of str pointer.
They are not linked.
you can change str without changing temp because it's like
*temp = &(str[0]);
*temp value is the address of 'a' from string "abcde"
if you str++
*temp value is the address of 'a' from string "abcde" and *str is the 'b'
i don't know what more i wan do for you.
This declaration
const char *str = "abcde";
means the following. There is allocated memory for variable str and it is initialized by the address of the first character of string literal "abcde"
In this declaration
const char *temp = str;
there is allocated memory for another pointer with name temp and the pointer gets a copy of the value stored in variable str.
So now you have two cells of memory each of them contains the address of the first character of the string literal.
This statement
str++; // hard to understand a point is here
means that the value stored in str was increased. The previous value was the address of the first character of the string literal. After increasing the value now it is equal to the address of the second character of the string literal.
You can check this by executing statements with a call to function printf before this statement and after it
printf( "%s\n", str );
str++; // hard to understand a point is here
printf( "%s\n", str );
The value stored in variable temp was not changed.
After this statement
temp++;
the both variables have equal values that are pointers to the second character of the string literal. The values stored in different cells of memory named str and temp.
After the second statement
temp++;
variable temp will have the value that equal to the address of the third character of the string literal. The value stored in variable str was not changed.
As you should know string literals include a terminating zero. You can output all characters of a string literal until the terminating zero will be encountered.
Consider the following code snippet
const char *str = "abcde";
const char *temp = str;
while ( *temp != '\0' ) printf( "%s\n", temp++ );
After the loop variable temp will have value that points to the terminating zero of the string literal. At the same time value stored in str will not be changed and will point to the first character of the string literal as before.

Strings and character with printf

I was confused with usage of %c and %s in the following C program:
#include <stdio.h>
void main()
{
char name[] = "siva";
printf("%s\n", name);
printf("%c\n", *name);
}
Output:
siva
s
Why we need to use pointer to display a character %c, and pointer is not needed for a string
I am getting error when I run
printf("%c\n", name);
I got this error:
str.c: In function ‘main’:
str.c:9:2: warning: format ‘%c’ expects type ‘int’, but argument 2 has type ‘char *’
If you try this:
#include<stdio.h>
void main()
{
char name[]="siva";
printf("name = %p\n", name);
printf("&name[0] = %p\n", &name[0]);
printf("name printed as %%s is %s\n",name);
printf("*name = %c\n",*name);
printf("name[0] = %c\n", name[0]);
}
Output is:
name = 0xbff5391b
&name[0] = 0xbff5391b
name printed as %s is siva
*name = s
name[0] = s
So 'name' is actually a pointer to the array of characters in memory. If you try reading the first four bytes at 0xbff5391b, you will see 's', 'i', 'v' and 'a'
Location Data
========= ======
0xbff5391b 0x73 's' ---> name[0]
0xbff5391c 0x69 'i' ---> name[1]
0xbff5391d 0x76 'v' ---> name[2]
0xbff5391e 0x61 'a' ---> name[3]
0xbff5391f 0x00 '\0' ---> This is the NULL termination of the string
To print a character you need to pass the value of the character to printf. The value can be referenced as name[0] or *name (since for an array name = &name[0]).
To print a string you need to pass a pointer to the string to printf (in this case name or &name[0]).
%c
is designed for a single character a char, so it print only one element.Passing the char array as a pointer you are passing the address of the first element of the array(that is a single char) and then will be printed :
s
printf("%c\n",*name++);
will print
i
and so on ...
Pointer is not needed for the %s because it can work directly with String of characters.
You're confusing the dereference operator * with pointer type annotation *.
Basically, in C * means different things in different places:
In a type, * means a pointer. int is an integer type, int* is a pointer to integer type
As a prefix operator, * means 'dereference'. name is a pointer, *name is the result of dereferencing it (i.e. getting the value that the pointer points to)
Of course, as an infix operator, * means 'multiply'.
The name of an array is the address of its first element, so name is a pointer to memory containing the string "siva".
Also you don't need a pointer to display a character; you are just electing to use it directly from the array in this case. You could do this instead:
char c = *name;
printf("%c\n", c);
If you want to display a single character then you can also use name[0] instead of using pointer.
It will serve your purpose but if you want to display full string using %c, you can try this:
#include<stdio.h>
void main()
{
char name[]="siva";
int i;
for(i=0;i<4;i++)
{
printf("%c",*(name+i));
}
}
The thing is that the printf function needs a pointer as parameter. However a char is a variable that you have directly acces. A string is a pointer on the first char of the string, so you don't have to add the * because * is the identifier for the pointer of a variable.
Or you can use %c like in the below code:
#include <stdio.h>
void main()
{
char name[]="siva";
//prints as string form
printf("%s\n",name);
//print each letter on different line
int size= sizeof(name);
int i;
for(i=0;i<size;i++){
printf("%c\n",name[i]);
}
}

Resources