Loading....
Coupon Accepted Successfully!

 

Question 1

Whats the difference between gets() and fgets()? Whats the correct way to use fgets() when reading a file?
 


Unlike fgets(), gets() cannot be told the size of the buffer it's to read into, so it cannot be prevented from overflowing that buffer. As a general rule, always use fgets(). fgets() also takes in the size of the buffer, so that the end of the array cannot be overwritten.


fgets(buffer, sizeof(buffer), stdin);
if((p = strchr(buffer, '\n')) != NULL)
{
  *p = '\0';
}



Also, fgets() does not delete the trailing "\n", as gets().


So whats the right way to use fgets() when reading a file?


while(!feof(inp_file_ptr)) 
{
  fgets(buffer, MAX_LINE_SIZE, inp_file_ptr);
  fputs(buffer, out_file_ptr);
}



The code above will copy the last line twice! This is because, in C, end-of-file is only indicated after an input routine has tried to read, and failed. We should just check the return value of the input routine (in this case, fgets() will return NULL on end-of-file); often, you don't need to use feof() at all.


This is the right way to do it


while(fgets(buffer, MAX_LINE_SIZE, inp_file_ptr)) 
{
  fputs(buffer, out_file_ptr);
}



Question 2

How can I have a variable field width with printf?
 


Use something like


printf("%*d", width, x);




Here is a C program...


#include  
#include  

#define WIDTH 5 

int main ( void ) 

    char str1[] = "Good Boy"; 
    char str2[] = "The earth is round"; 

    int width = strlen ( str1 )  + WIDTH; 
    int prec  = strlen ( str2 )  + WIDTH; 

    printf ( "%*.*s\n", width, prec, str1 ); 
    return 0; 
}



Question 3

What does alloca() do?
 


alloca() allocates memory which is automatically freed when the function which called alloca() returns. However, note that alloca() is not portable and its usage is not recommended.

Question 4

Can you compare two strings like string1==string2? Why do we need strcmp()?
 


Do you think this will work?


if(string1 == string2)
{

}



No!, strings in C cannot be compared like that!.

The == operator will end up comparing two pointers (that is, if they have the same address). It wont compare the contents of those locations. In C, strings are represented as arrays of characters, and the language never manipulates (assigns, compares, etc.) arrays as a whole.

The correct way to compare strings is to use strcmp()


if(strcmp(string1, string2) == 0) 
{

}



Question 5

What does printf() return?
 


Upon a successful return, the printf() function returns the number of characters printed (not including the trailing '\0' used to end output to strings). If the output was truncated due to this limit then the return value is the number of characters (not including the trailing '\0') which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated. If an output error is encountered, a negative value is returned.

There is a very funny yet interesting interview question around this....

Look at the code below.


void main() 

   if(X) 
  { 
     printf("Hello"); 
  } 
  else 
  { 
     printf(" World"); 
  } 




What should X be replaced with inorder to get the output as "Hello World"?


And here comes the answer....


#include  
int main() 

    if(!printf("Hello")) 
    { 
        printf("Hello"); 
    } 
    else 
    { 
        printf(" World"); 
    } 




Kind of stupid isn't it? But they do ask these type of questions. Believe me!

Question 6

What do setjmp() and longjump() functions do?
 


It is not possible to jump from one function to another by means of a goto and a label, since labels have only function scope. However, the macro setjmp and function longjmp provide an alternative, known as a non-local goto, or a non-local jump. The header file declares something called a jmp_buf, which is used by the cooperating macro and function to store the information necessary to make the jump. The declarations are as follows:


#include 
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);



The setjmp macro is used to initialise the jmp_buf and returns zero on its initial call. Then, it returns again, later, with a non-zero value, when the corresponding longjmp call is made! The non-zero value is whatever value was supplied to the call of longjmp.

This is best explained by way of an example:


#include 
#include 
#include 

void func(void);
jmp_buf place;

main()
{
   int retval;

    /*
     * First call returns 0,
     * a later longjmp will return non-zero.
     */

     if(setjmp(place)) != 0)
     {
        printf("Returned using longjmp\n");
        exit(EXIT_SUCCESS);
     }

     /*
      * This call will never return - it
      * 'jumps' back above.
      */

     func();
     printf("What! func returned!\n");
}

void func(void)
{
     /*
      * Return to main.
      * Looks like a second return from setjmp,
      * returning 4!
      */
  
     longjmp(place, 4);
     printf("What! longjmp returned!\n");
}




The val argument to longjmp is the value seen in the second and subsequent ?returns? from setjmp. It should normally be something other than 0; if you attempt to return 0 via longjmp, it will be changed to 1. It is therefore possible to tell whether the setjmp was called directly, or whether it was reached by calling longjmp. If there has been no call to setjmp before calling longjmp, the effect of longjmp is undefined, almost certainly causing the program to crash. The longjmp function is never expected to return, in the normal sense, to the instructions immediately following the call. All accessible objects on ?return? from setjmp have the values that they had when longjmp was called, except for objects of automatic storage class that do not have volatile type; if they have been changed between the setjmp and longjmp calls, their values are indeterminate.

The longjmp function executes correctly in the contexts of interrupts, signals and any of their associated functions. If longjmp is invoked from a function called as a result of a signal arriving while handling another signal, the behaviour is undefined.

It's a serious error to longjmp to a function which is no longer active (i.e. it has already returned or another longjump call has transferred to a setjmp occurring earlier in a set of nested calls).

The Standard insists that, apart from appearing as the only expression in an expression statement, setjmp may only be used as the entire controlling expression in an if, switch, do, while, or for statement. A slight extension to that rule is that as long as it is the whole controlling expression (as above) the setjmp call may be the subject of the ! operator, or may be directly compared with an integral constant expression using one of the relational or equality operators. No more complex expressions may be employed.

Examples are:


setjmp(place);                    /* expression statement */
if(setjmp(place)) ...             /* whole controlling expression */
if(!setjmp(place)) ...            /* whole controlling expression */
if(setjmp(place)  if(setjmp(place)<;4 && 1!=2) ...  /* forbidden */



Question 7

How can I specify a variable width in a scanf() format string?
 


You cant!.

An asterisk in a scanf() format string means to suppress assignment. You may be able to use ANSI stringizing and string concatenation to accomplish about the same thing, or you can construct the scanf format string at run time.

Question 8

How can I convert numbers to strings (the opposite of atoi)?
 


Use sprintf()

Note!, since sprintf() is also a variable argument function, it fails badly if passed with wrong arguments or if some of the arguments are missed causing segmentation faults. So be very careful when using sprintf() and pass the right number and type of arguments to it!

Question 9

Why should one use strncpy() and not strcpy()? What are the problems with strncpy()?
 


strcpy() is the cause of many bugs. Thats because programmers almost always end up copying more data into a buffer than it can hold. To prevent this problem, strncpy() comes in handy as you can specify the exact number of bytes to be copied.

But there are problems with strncpy() also. strncpy() does not always place a '\0' terminator in the destination string. (Funnily, it pads short strings with multiple \0's, out to the specified length). We must often append a '\0' to the destination string by hand. You can get around the problem by using strncat() instead of strncpy(): if the destination string starts out empty, strncat() does what you probably wanted strncpy() to do. Another possibility is sprintf(dest, "%.*s", n, source). When arbitrary bytes (as opposed to strings) are being copied, memcpy() is usually a more appropriate function to use than strncpy().

Question 10

How does the function strtok() work?
 


strtok() is the only standard function available for "tokenizing" strings.


The strtok() function can be used to parse a string into tokens. The first call to strtok() should have the string as its first argument. Subsequent calls should have the first argument set to NULL. Each call returns a pointer to the next token, or NULL when no more tokens are found. If a token ends with a delimiter, this delimiting character is overwritten with a "\0" and a pointer to the next character is saved for the next call to strtok(). The delimiter string delim may be different for each call.

The strtok_r() function works the same as the strtok() function, but instead of using a static buffer it uses a pointer to a user allocated char* pointer. This pointer must be the same while parsing the same string.


An example


main()
{
    char str[]="This is a test";
    char *ptr[10];
    char *p;
    int i=1;
    int j;

    p=strtok(str," ");

    if(p!=NULL)
    {
        ptr[0]=p;
        while(1)
        {
            p=strtok(NULL, " ");

            if(p==NULL)break;
            else
            {
               ptr[i]=p;i++;
            }
        }
    }
    
    for(j=0;j     {
            printf("\n%s\n", ptr[j]);
    }
}



 




Test Your Skills Now!
Take a Quiz now
Reviewer Name