strings in c
| July 9, 2011 | Posted by kaswan under C-related Stuff |
There is a warning related to this article.This is going to be long.
There are large number of articles on web about strings yet most of us are unclear
This is not a beginner article..
What is string anyway?
a array of variable number of characters…
so “ah” and “aahah” both are string.This is the main source of problem.variable length.
in c string is not a data type. It is a data structure.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int main(){ char str[]="hello"; char a=5,*p; p=&a; printf("%pn",p); // output some address printf("%p",str);// also output some address } |
in the above case a array named str of size 6 is made.str is the base address of this array.str[0] is first element and str[6] is last element(‘�’).
at this sight you will not find any difference between str and p
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int main(){ char str[]="hello"; char a=5,*p; p=&a; printf("%p %pn",p,&p); // 2 different address printf("%p%p",str,&str);// 2 same address } |
So what is this.Actually you can think it like that.P is a container holding a memory address.This container is somewhere in the memory, address of which can be obtained by &p.But str is like a label or user friendly view of address.&str doesn’t exist as a separate memory location in memory.since str is not a container you can’t put anything in it..
technically speaking str is only rvalue but str[0],str[1].. are both rvalue and lvalue.
str=some_address // wrong
but you can access its value.
|
1 2 3 4 5 6 7 |
int main(){ char str[]="hello"; char *a=str;// or a=&str same thing } |
now since str is representing a address we can use it to access individual elements or whole string
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
int main(){ char str[]="hello hi"; str[0]='e'; printf("%c",str[0]);// printf("%c",*str); printf("%c",*(str+1)); printf("%s",str); printf("%s",&str); } |
what will happen if your string doesn’t fit in the given array size.
|
1 2 3 4 5 6 7 8 9 10 11 |
int main(){ /*automatically overwrite str[5] location with null value*/ /*This is not working for strings smaller then 3 characters on my compiler*/ char str[4]="hell"; printf("%s",str);//output hell } |
if you have character array then you can convert it into string
|
1 2 3 4 5 6 7 8 9 10 11 |
int main(){ char str[3]={'a','b','c'}; printf("%s",str);// not work str[3]='�';//0=>'a',1=>'b','2'=>'c',3=>'�' printf("%s",str);// output "abc" } |
i have seen something like this..
char *p=”hey”;
if you have seen this then you probably should have seen this also
printf(“something”);
“something” is called a string literal.Anything which is inside “” is called a string literal.This literal is actually a name of the string array.
|
1 2 3 4 5 |
int main(){ printf("%c %c",*"hey","hey"[0]); // output h h } |
a string literal will occupy same memory location if it has same name no matter how many times it is used or defined.
|
1 2 3 4 5 6 |
/*p is used to print full hexadecimal address*/ char *p="hey"; printf("%pn","hey"); printf("%p",p); |
if the string literals are different then
|
1 2 3 4 5 6 7 8 |
int main(){ char *p="hey"; printf("%pn",p);// different address printf("%p","hello");// different address } |
But you can’t change these literals as they reside in read only memory.
|
1 |
"hey"[0]='a';// error changing read only memory |
|
1 2 3 4 5 6 7 |
int main(){ char *p="hello"; p[0]='e';// error program will get crash } |
but
|
1 2 3 |
char str[]="hey"; str[0]='a';// not error |
in the above case “hey” is not stored as a string literal but it is stored as an array
you can verify this by looking at the address of two strings one is array string and another is string literal .
both the strings have same characters.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int main(){ char str[]="hello";// array string char *p="hello";// string literal <=> p = &"hello" printf("%p","hello");//same printf("%p",p); // address printf("%p",str);// different address } |
so final conclusion is this
strings are of two types(based on how they are stored?) array strings and string literal.
array strings are stored in arrays with default read write access and string literal are stored as read only memory.
lets do some practice..
what is the output of this program?
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
int main(){ char a[]="abcdef"; char *p="ank"; printf(a);//output abcdef printf(a+3);//output def printf(p);//output ank printf(1+"ank");//output nk } |
important one…
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
int main(){ char *str1[]="crazy"; char *str2[]="crazy"; char *p1="crazy",*p2="crazy"; if(str1==str2)//false printf("equal 1"); if(p1==p2)//true printf("equal 2"); if("crazy"==p1)//true remember you are comparing address! printf("equal 3"); if("crazy"==str1)// false printf("equal 4"); } |
you can even find their sizes
|
1 2 3 4 5 6 7 8 9 |
int main(){ char str[]="hello"; char *p="hello"; printf("%d %d %d",sizeof(str),sizeof("hello"),sizeof(p));//output 6 6 4 } |
now what would you do if you want to store array of strings?
|
1 2 3 4 5 |
int main(){ char *a[]={"hel1","hel2","hel3","hel4"}; } |
if i ask you how much memory is allocated to a?
the correct answer is 16.(4 pointers to hold 4 address .memory=(4*no of pointers))
so where are the 4 strings?
these are 4 string literals which are in the read only memory .you can access every literal or character in a literal but you can’t change any of the literal.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
int main(){ char *a[]={"abcd","ef","ghi","jklmn"}; for(i=0;i<4;++i) printf("%s",a[i]); /* *you can also do the same in this way. */ for(i=0;i<4;++i) printf("%s",*(a+i)); } printf("%c",*(a[0]+1));//output b printf("%s",a[0]+1);//output substring bcd |
lets see if we what we can change
|
1 2 3 4 5 6 7 8 9 |
int main(){ char *p="xyz"; for(i=0;i<4;++i) a[i]=p;// same as *(a+i)=p } |
resulting array of strings is {“xyz”,”xyz”,”xyz”,”xyz”}
|
1 2 3 4 5 |
int main(){ *(a[0]+1)='e';// error changing read only location } |
There is another method to declare array of strings.The difference between this and previous one is same as the difference between char a[]=”sdds” and char *p=”wed”;
|
1 2 3 4 5 6 7 8 9 10 11 |
int main(){ char a[][6]={"hey","how","are","you"}; char a[4][4]; for(i=0;i<4;++i) scanf("%d",&a[i]);// input "hey","how","are","you" } |
in the above case a two dimensional array is allocated.every position have both read and write permission
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int main(){ char *p[]={"hey","hi"}; char q[][4]={"hey","hi"}; *(p[0]+0)='l';//not allowed q[0][0]='l';//allowed printf("%s",q[0]);// output ley } |
you can even check that same string literals have same address no matter where they are stored or used..
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
int main(){ char p[][5]={"abc","abc","def"}; char *q[]={"abc","abc","def"}; q[0]==q[1]?printf("y1"):printf("n1"); q[1]=="abc"?printf("y2"):printf("n2"); q[0]=="abc"?printf("y3"):printf("n3"); q[0]==&"abc"?printf("y4"):printf("n4"); p[0]==p[1]?printf("y5"):printf("n5"); p[0]=="abc"?printf("y6"):printf("n6"); p[0]==&"abc"?printf("y7"):printf("n7"); *q==&"abc"?printf("y8"):printf("n8"); *(q+1)=="abc" ?printf("y9"):printf("n9"); *(*(q+1)+1)=='b'?printf("y10"):printf("n11"); *((*q+1)+1)=='b'?printf("y12"):printf("n12"); p[0][0]==p[1][0]?printf("y13"):printf("n13"); sizeof(q)==12?printf("y14"):printf("n14"); sizeof(p)==12?printf("y15"):printf("n15"); sizeof(p)==15?printf("y16"):printf("n16"); } |
Sorry for the long question but it will definitely open your mind .




Recent Comments