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.
Related
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.
I wrote this code
#include <stdio.h>
int main()
{
char String[] = "Hello the world!";
char *pointer = String;
int i;
printf(" %s\n", pointer);
pointer = "Helllooooo the worlldddddd";
printf("Hello %s\n", pointer);
printf("Hello %s\n", String);
return 0;
}
but I can't understand how this line works fine.
pointer = "Helllooooo the worlldddddd";
but I got this output
Hello the world!
Hello Helllooooo the worlldddddd
Hello Hello the world!
As you see it couldn't change String value but it shows more than the original number of characters. Shouldn't this cause a buffer overflow? Won't that destroy other variables?
When you write the line
pointer="Helllooooo the worlldddddd";
you are not saying "take the array pointed at by pointer and overwrite its contents with the string "Helllooooo the worlldddddd"," but rather "change which string pointer points at so that it's now pointing at the string ""Helllooooo the worlldddddd"." This accounts for why you're seeing the original string printed out when you directly print String - you never actually modified it. As a result, you don't need to worry about overflowing your array here, since you're not actually writing anything to it.
On the other hand, if you wrote
strcpy(pointer, "Helllooooo the worlldddddd");
which actually does copy the contents of the new string into the buffer pointed at by pointer, then you would have a buffer overflow, which would be a problem. But notice that this is a very different operation that explicitly says "please copy the contents of this string to this location" rather than "change where this pointer points."
you have initialize a pointer which point to String "Hello the world " char *pointer=String; so far so good .
first printf printf(" %s\n",pointer);, you have printed the pointer which point to "Hello the world".
then you set the pointer to point anew string "Hellloooooo the worllddddd" pointer="Helllooooo the worlldddddd";.
then you have printed the pointer which point in this case to "Hellloooooo the worllddddd"printf("Hello %s\n",pointer); .
last printf you have printed the string "Hello the world" printf("Hello %s\n",String);.
Note:.
((takecare that you have printed in second printf("Hello %s\n",String); and third printf printf("Hello %s\n",String); the string hello which will be printed before the value of the pointer or the string))
#include <stdio.h>
int main()
{
char String[]="Hello the world"; // the string
char *pointer=String; // pointer to string
char i; //counter
printf(" %s\n",pointer); // print current value of pointer
pointer="number of char"; // new value to replace the string
for (i=0;i<14;i++) // you cannot change the content of array without using loop
{
String[i] = pointer[i]; // char i in string = ti char i in pointer
}
printf("Hello %s\n",pointer); // print value of pointer
printf("Hello %s\n",String); // print value of string
return 0;
}
i think that what are you trying to do.
One more quick option for you to consider when manipulating strings:
The string function strdup(...); allows the copying of an existing string into a newly created string in one easy step. (or at least one in which all the complexity has been abstracted away):
char *pointer = strdup("Helllooooo the worlldddddd");
The new string pointer can now be used to contain any string up to len long, where len is defined as:
int len = strlen(pointer);//len is 26 after using strdup(...); above
So for example, because your example string is shorter than len:
char String[]="Hello the world!";//length is 16
you could copy it into pointer without a buffer overflow:
strcpy(pointer, String);
Strings created using strdup(...): need to be free'd to avoid memory leaks. Call the following when you are finished using pointer:
free(pointer);
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.
This is my code and when I run it, I am getting segmentation fault.
char *s = NULL;
s = (char *)malloc(5*sizeof(char));
s[0]='10';
s[1]='20';
printf("%s",s[1]);
please tell where the error is and why this is happening. My intension of the program is to dynamically create a string, give it some value byte by byte and print the values byte by byte.
Is there any way to add integer values to string. Because, I have a situation where length of string is to be in first part of string followed by data. Kindly suggest any method to do this in C.
printf("%s", s[1]); means print string starting at address (int)'20'. That's clearly a bug. Should be: s[2]='\0'; printf("%s", s+1 /*&s[1]*/);
You are storing multibyte characters in s[0] and s[1]. Beside of this use %c format specifier to print a character.
1.s[0] is a char you can not assign 10 to it. (It will compile with warnings but it is not doing what you have expected)
2.printf("%s",s[1]); will also cause undefined behavior as string followed bys[1] is not null terminated.
Don't cast the result of malloc and family.
s[0] and s[1] will take only one byte value.
Then your string is not a null terminated string.
Try this.
s[0]='h';
s[1]='i';
s[2]='\0';
printf("%s",s);
%s is for printing the string. Use %c for printing the character.
printf("%c",s[1]);
You can use like this to store the integer into an char array,
char *s=malloc(123);
sprintf(s,"%d",integer_value);
Then use strcat to store the string in that.
Passing to the function use like this,
void func(char *);
main() {
. . .
func(s);
. . .
}
void func(char *str)
{
// do what you need
}
if between integer and string slash is available ( like in your comment) you can use the strtok function. Before using the strtok function take backup for your string. It will modify your content. Or els you can use like this,
sscanf(str,"%d / %s",&int,string);
Now string have the value "hello".
char s[10];
sprintf(s,"%d",int);
strcat(str,s);
Try this,
int fd;
char str[]="data7";
char st[12];
sscanf(str,"%[^ 0-9] %d",st,&fd);
printf("st:%s\tfd:%d\n",st,fd);
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.