Wednesday, November 2, 2011

More about Strings in C programming language

In what way are character arrays different than numeric arrays? Can elements in a character array be accessed in the same way as the elements of a numeric array? Do I need to take any special care of ‘\0’? Why numeric arrays don’t end with a ‘\0’? Declaring strings is okay, but how do I manipulate them? Questions galore!! Well, let us settle some of these issues right away with the help of sample programs.

/* Program to demonstrate printing of a string */
main( )
{
  char  name[ ] = "Klinsman" ;
  int  i = 0 ;

  while ( i <= 7 )
 {
    printf ( "%c", name[i] ) ;
  i++ ;
 }
}

And here is the output...

Klinsman

No big deal. We have initialized a character array, and then printed out the elements of this array within a while loop. Can we write the while loop without using the final value 7? We can; because we know that each character array always ends with a ‘\0’. Following program illustrates this.

main( )
{
      char  name[ ] = "Klinsman" ;
      int  i = 0 ;

      while ( name[i] != `\0' )
 {
            printf ( "%c", name[i] ) ;
  i++ ;
 }
}

And here is the output...

Klinsman

This program doesn’t rely on the length of the string (number of characters in it) to print out its contents and hence is definitely more general than the earlier one. Here is another version of the same program; this one uses a pointer to access the array elements.  

main( )
{
      char  name[ ] = "Klinsman" ;
      char  *ptr ; 
ptr = name ;  /* store base address of string */

      while ( *ptr != `\0' )
 {
            printf ( "%c", *ptr ) ;
  ptr++ ;
 }
}

As with the integer array, by mentioning the name of the array we get the base address (address of the zeroth element) of the array. This base address is stored in the variable ptr using,

ptr = name ;

Once the base address is obtained in ptr, *ptr would yield the value at this address, which gets printed promptly through,

printf ( "%c", *ptr ) ;

Then,  ptr is incremented to point to the next character in the string. This derives from two facts: array elements are stored in contiguous memory locations and on incrementing a pointer it points to the immediately next location of its type. This process is carried out till ptr doesn’t point to the last character in the string, that is, ‘\0’. In fact, the character array elements can be accessed exactly in the same way as the elements of an integer array. Thus, all the following notations refer to the same element:

name[i]
*( name + i )
*( i + name )
i[name]

Even though there are so many ways (as shown above) to refer to the elements of a character array, rarely is any one of them used. This is because printf( ) function has got a sweet and simple way of doing it, as shown below. Note that printf( ) doesn’t print the ‘\0’.

main( )
{
      char  name[ ] = "Klinsman" ;
      printf ( "%s", name ) ;
}

The %s used in printf( ) is a format specification for printing out a string. The same specification can be used to receive a string from the keyboard, as shown below. 

main( )
{
      char  name[25] ;

      printf ( "Enter your name " ) ;
      scanf ( "%s", name ) ;
      printf ( "Hello %s!", name ) ;
}

And here is a sample run of the program...

Enter your name Debashish
Hello Debashish!

Note that the declaration char name[25] sets aside 25 bytes under the array name[ ], whereas the scanf( ) function fills in the characters typed at keyboard into this array until the enter key is hit. Once enter is hit, scanf( ) places a ‘\0’ in the array. Naturally, we should pass the base address of the array to the scanf( ) function.
While entering the string using scanf( ) we must be cautious about two things:

(a)  The length of the string should not exceed the dimension of the character array. This is because the C compiler doesn’t perform bounds checking on character arrays. Hence, if you carelessly exceed the bounds there is always a danger of overwriting something important, and in that event, you would have nobody to blame but yourselves.

(b)  scanf( ) is not capable of receiving multi-word strings. Therefore names such as ‘Debashish Roy’ would be unacceptable. The way to get around this limitation is by using the function gets( ). The usage of functions gets( ) and its counterpart puts( ) is shown below.

 main( ) 
{
     char  name[25] ;

     printf ( "Enter your full name " ) ;
     gets ( name ) ;
     puts ( "Hello!" ) ;
     puts ( name ) ;
}

 And here is the output...

 Enter your name Debashish Roy
Hello!
Debashish Roy 

 The program and the output are self-explanatory except for the fact that, puts( ) can display only one string at a time (hence the use of two puts( ) in the program above). Also, on displaying a string, unlike printf( ), puts( ) places the cursor on the next line. Though gets( ) is capable of receiving onlyone string at a time, the plus point with gets( ) is that it can receive a multi-word string. If we are prepared to take the trouble we can make scanf( ) accept multi-word strings by writing it in this manner:

 char  name[25] ;
printf ( "Enter your full name " ) ;
scanf ( "%[^\n]s", name ) ;

 Though workable this is the best of the ways to call a function, you would agree.

No comments:

Post a Comment