I have a very stupid question, I just can't answer.
Can somebody tell me why the following code works?
char hello[]="Hello World\n";
char *hptr = hello;
while(*hptr)
{
printf("%c", *hptr++);//here the output must be "ello World", but C thinks otherwise!!!
}
You're using a post-increment:
*hptr++
This uses the value of hptr first, and then increments it. If you wanted to skip the first letter, you would use a pre-increment:
*++hptr
This increments the pointer value, then uses it as a function argument.
char hello[]="Hello World\n";
In this hello hold the address of the first index of the character array
char *hptr = hello;
here the character pointer hptr=address of the first index of your character array
while(*hptr)
{
printf("%c", *hptr++);
}
and in this loop it first prints the character at your first index of the character array and then increments it and then increments the address of hptr and then the second character is printed and this goes on till u reaches the null character.
Related
I'm new to C and pointers, so i have this problem. I want to tell to pointer how much memory it should point to.
char * pointer;
char arr[] = "Hello";
pointer = arr;
printf("%s \n", pointer);
This pointer will point to whole array, so i will get "Hello" on the screen. My question is how can i make pointer to only get "Hel".
You may try this:
char * pointer;
char arr[] = "Hello";
pointer = arr;
pointer[3] = '\0'; // null terminate of string
printf("%s \n", pointer);
If you always work with strings, then have a look at strlen for getting length of a string. If a string arr has length l, then you may set arr[l/2] = '\0', so that when you print arr, only its first half will be shown.
You may also want to print the last half of your string arr? You can use pointer to point to any place you want as the start. Back to your example, you may try:
char * pointer;
char arr[] = "Hello";
pointer = arr + 2; // point to arr[2]
printf("%s \n", pointer);
Have a check what you will get.
printf has the ability to print less than the full string, using the precision value in the format string. For a fixed number of characters (e.g. 3), it's as simple as
printf( "%.3s\n", pointer );
For a variable number of characters, use an asterisk for the precision, and pass the length before the pointer
int length = 3;
printf( "%.*s\n", length, pointer );
You don't know what a pointer is so I'll explain.
A pointer does not point to a string. It points to a char! Yes, a char. A string in C is really just a set of chars all one after the other in the memory.
A char* pointer points to the beginning of a string. The string ends when there is a '\0' (aka null) char. When you printf("%s",s), what printf does is a cycle like this:
int i;
for(i=0;1;i++) //infinite cycle
{
if(s[i]=='\0')
break;
printf("%c",s[i]);
}
Meaning it will not print a string but all the chars in a char array until it finds a null char or it goes into memory space that is not reserved to it (Segmentation fault).
To print just the 1st 3 characters you could do something like this:
void printString(char* s,int n) //n=number of characters you want to print
{
if(n>strlen(s))
n=strlen(s);
else if(n<0)
return;
char temp=s[n]; //save the character that is in the n'th position of s (counting since 0) so you can restore it later
s[n]='\0'; //put a '\0' where you want the printf to stop printing
printf("%s",s); //print the string until getting to the '\0' that you just put there
s[n]=temp; //restore the character that was there so you don't alter the string
}
Also, your declaration of pointer is unnecessary because it is pointing to the exact same position as arr. You can check this with printf("%p %p\n",arr,pointer);
How much of the string is printed is controlled by the NULL-character "\0", which C automatically appends to every string. If you wish to print out just a portion, either override a character in the string with a "\0", or use the fwrite function or something similar to write just a few bytes to stdout.
You could achieve the objective with a small function, say substring.
#include<stdio.h>
#include<string.h> // for accessing strlen function
void substring(char* c,int len)
{
if (len <= strlen(c)){
*(c+len)='\0';
printf("%s\n",c);
}
else{
printf("Sorry length, %d not allowed\n",len);
}
}
int main(void)
{
char c[]="teststring";
char* ptr=c;
substring(ptr,4); // 4 is where you wish to trim the string.
return 0;
}
Notes:
In C++ a built-in function called substring is already available which shouldn't be confused with this.
When a string is passed to a function like printf using a format specifier %s the function prints all the characters till it reaches a null character or \0. In essence, to trim a string c to 4 characters means you put c[4] to null. Since the count starts from 0, we are actually changing the 5th character though. Hope the example makes it more clear.
Let's say I have function that has a char array as its parameter and char* as its return type. I want to return a pointer to the subarray of the parameter array.
For example : char str[] = "hi billy bob";
I want my function to return "billy bob";
Let's say in the body of my function I was able to get the index
of where I want the subarray to start.
char* fun(const char s1[]) {
int index = a random int;
/* char *p = *(s1[index1]); */
return p;
}
I'm having trouble with the commented out line.
Simply use
const char *p = &str[index]; /* may also write p = str + index */
return p;
The above takes the address of the character at index index -- which is a pointer to char array beginning at this index. The string continues until the first '\0' character which is the end of the original str.
In your case, if you want the output to be "billy bob" (Note that you cannot change the capitalization unless you modify the string or return a new one) you should set index = 3;.
It gets more involved when you want to take a substring of str. Then you either have to set str[end_index]='\0' or use malloc to allocate a new array and copy the relevant part.
Some information regarding the two syntax options
In C, the expression a[i] is equivalent to *(a+i). I.e., take the pointer a, move it forward i elements (chars in your case) and then return the element at the resulting address.
If you prefix a[i] with an & operator to get the address of that character. So &a[i] may be written as &*(a+i). The operators '&' and '*' cancel each other and you are left with a+i.
What you want is this
char *random_sub_string(const char *string)
{
size_t length;
if (string == NULL)
return NULL;
length = strlen(string);
return string + rand() % length;
}
char *fun(const char str[])
{
int index = x; /* where `x' is some non-negative value less than the
length of the input string */
return str + index;
}
This is the cleanest way of returning the string you're looking to return. The main idea here is that, in C, a string is defined as a null-terminated array of characters. Null-terminated means the array contains the \0 character, and the location of the \0 denotes the end of the string. Moreover, a char[] and char * are both pointers to a char. Thus, they can be accessed in the same way. In the return statement above, we make use of pointer arithmetic to compute a pointer to a substring of the input string. If you're not familiar with pointer arithmetic, it would be a good idea to read up on it.
I am nowhere lose to even guessing how come we get the given output . Can I please get some explanation? Also, any short and quick resources to try similar questions?
void main()
{
struct a
{
char ch[10];
char *str;
};
struct a s1={"Hyderabad","Bangalore"};
printf("\n%c%c",s1.ch[0],*s1.str);
printf("\n%s%s",s1.ch,s1.str);
getch();
}
Ans: HB, HyderabadBangalore
struct a s1={"Hyderabad","Bangalore"}; assigns "Hyderabad" to ch and "Bangalore" to str.
printf("\n%c%c",s1.ch[0],*s1.str); prints the first character of the strings. Since ch is an array, ch[0] represents its first character. Since str is a character pointer, it points to the first character of a string here. So, *s1.str will have value 'B'
printf("\n%s%s",s1.ch,s1.str); simply prints all characters of both strings.
Fundamentally, ch is equal to &ch[0], the address of the first character in the array. And, str is pointer variable which holds the address of first character of the string literal "Bangalore".
%c is only for single character. Example H.
$s is for string. Example Hyderabad.
s1.ch[0] points to first character of String ch ->H
*s1.str is a pointer. It points to the value stored at address of str. It will be ->B
Hence you get HB
\n means a new line (as in java).
Here is your output according to requested question
void main()
{
struct a
{
char ch[10];
char *str;
};
struct a s1={"Hyderabad","Bangalore"};
printf("%c%c",s1.ch[0],*s1.Str[0]);
printf("\t%s%s",s1.ch,s1.str);
getch();
}
I am new to C and I would like to know the difference between the below two snippet codes.When I try executing first one it works fine,but when I run the second one it gives me segmentation fault.Whats the reason for this behavior?
printf("%c\n",*strptr++);
printf("%c\n",*(strptr+i));
Here is the below code.
#include<stdio.h>
int main(void)
{
char str[100]="My name is Vutukuri";
int i=0;
char *strptr;
strptr=str;
while(*strptr != '\0')
{
printf("%c\n",*strptr++);
//printf("%c\n",*(strptr+i));
//i++;
}
return 0;
}
Entirely different.
The first snippet prints the character at strptr and then increments strptr by one.
The second snippet prints the character at strptr + i.
Apparently, the address strptr refers to an allocated place in memory, while strptr + i points to an unallocated place. If you allocate a string as
char s[LENGTH];
or
char* s = (char*)malloc(LENGTH * sizeof(char));
then you can only use the characters from s[0] to s[LENGTH - 1] (and the string itself can only be LENGTH - 1 long, so there is place for a null terminator). In your case, the pointer strptr + i is probably not in the range s...s + LENGTH - 1.
Maybe you want to replace i with 1.
++ operator first uses the initial value, and then it increments it.
+operator calculates the new value and then uses it.
I am practicing using pointers.
I have a pointer to an array of 3 strings: "dog", "cat", "rat".
I can print the contents using a for loop and using an array.
However, I am having problems printing them using pointer arithmetic. I would like to increment the pointer to the next element in the array. However, all it does is print the dog letters.
Code:
int main(int argc, char **argv)
{
char *str[3] = { "DOG", "CAT", "RAT"};
int i = 0;
/* display using an array element */
for(i = 0; i < 3; i++)
{
printf("str: %s\n", str[i]);
}
/* display using a pointer arthimatic */
while((*str)++)
{
printf("str: %s\n", str);
}
getchar();
return 0;
}
How can I accomplish this?
Edit:
Code:
while(str)
{
printf("str: %s\n", *(str++));
}
However, I get this error message. Doesn't the I-value have to be a variable of some sort?
error C2105: '++' needs l-value
You first have to get a pointer, and you would need a condition when to stop. A last NULL pointer can be used for that. So the code becomes
char *str[] = { "DOG", "CAT", "RAT", NULL };
char **elem_p = str;
/* display using a pointer arthimatic */
while(*elem_p) {
printf("str: %s\n", *elem_p);
elem_p++;
}
What you did was to increment the pointer stored in the array's first element. That pointer will never too soon equal to a null pointer (if at all), So, the loop will not stop until that pointers' internal value overflows or something else happens so that it equals to a null pointer. Then, you pass a pointer to the arrays first element to printf (you pass the array, but the compiler will convert it to a pointer - see below). Printf will interpret the bytes of those pointers as characters and print them, which will result in garbage printed out if it doesn't crash right away.
You want to increment at a higher level instead: Increment not one element (pointer) of the array, but the pointer to the elements itself. Now, you can't do
str++
Because str is an array. It's not a pointer, even though it can be converted to a pointer, which will then point to the first element of it. So, we create a pointer which points to str[0] initially, but increment it all again. Note that we increment it after printing, so that we print out the first element too.
Actually, i think i should explain why you can't do str++. Well, str is an array. An array is an object that occupies some fixed amount of storage. Above, the array occupies 4 times the size of a char pointer, 4 * sizeof(char*). What looks like a pointer at the first glance is a block of elements of the same type. For addressing elements, the compiler can make up a pointer out of an array in expressions, which then can be used to address elements in the array. If you do str++, the compiler will create a pointer for you. But that pointer is temporary, exists only for a short while for the sole purpose of immediately doing something with it, but it can not be changed like being incremented. That is the reason that we create a real pointer variable that we then can increment.
The problem with your code is that you're incrementing the dereferenced pointer str, which gives you a char * to the first element in the array (ie, dog).
You should be incrementing str itself, not what it points to.
However your loop termination check won't work in that case as there is no element in the array at the moment for which str == 0 holds true. In order to get that to work, you'll need to add a fourth element to the array that is 0.
str, being an array, cannot be incremented.
Right now, you're incrementing (*str), which is str[0]: the first element of that array. Since this element is a pointer, you're incrementing the pointer, making it reference the subsequent elements of the string "DOG".
What you need is a pointer that can point to (and thus walk over) str's elements. Since the elements are char*, the pointer to them would be char** - a double pointer.
(*str)++
Increments the value pointed to by s. You will need to increment the pointer itself and print the value of the pointee. Note, that str is not a l-value and you cannot increment it either.
Also, if you increment first, then you are left with only two legal strings that you can print. You invoke UB after that.
Try this:
int main(void)
{
/* we have added a sentinel to mark the end of the array */
char *str[] = { "DOG", "CAT", "RAT", 0 };
/* since str is an array, you cannot use it to loop, have a walker */
char **w = str;
/* display using a pointer arthimatic */
while(*w)
{
printf("str: %s\n", *w++);
}
return 0;
}
Look up operator precedence and binding in C.
while((*str)++)
{ printf("str: %s\n", str); }
This increments *str which is the letter 'd'. You don't want to do that. You want to increment the pointer. This code should do what you want:
while((str)++)
{ printf("str: %s\n", str); }