Rewrite readlines to store lines in an array supplied by main, rather than calling alloc to maintain storage.How much faster is the program?

#include <string.h>

#define    MAXLEN    1000    /* maximum length of line */
#define    MAXSTOR   5000   /* size of available storage space */

int getline(char *, int);

/* readlines:read input lines */
int getlines(char *lineptr[], char *linestor, int maxlines){
    int len, nlines;
    char line[MAXLEN];
    char *p =linestor;
    char *linestop = linestor + MAXSTOR;

    nlines = 0;
    while((len = getline(line, MAXLEN)) > 0)
       if(nlines >= maxlines || p + len > linestop)
           return -1;
       else{
            line[len - 1] = '\0';    /* delete newline */
            strcpy(p ,line);
            lineptr[nlines++] = p;
            p += len;
       }
    return nlines;
}

Rewrite appropriate programs from earlier chapters and exercises with pointers instead of array indexing.Good possibilities include getline, atoi, itoa, and their variants, reverse and strindex and getop

#include <stdio.h>

/*getline: read a line into s, return length */
int getline(char *s, int lim){

   int c;
   char *t = s;

   while(--lim > 0 && (c =getchar()) != EOF && c != '\n')
         *s++ = c;
   if(c == '\n')
        *s++ = c;
   *s = '\0';
   return s - t;
}

#include <ctype.h>

/* atoi:convert s to integer; pointer version   */
int atoi(char *s){
   int n, sign;
   for(; isspace(*s); s++)    /* skip white space */
         ;
   sign = (*s == '-') ? -1 : 1;
   if(*s == '+' || *s == '-')  /* skip sign */
          s++;
   for(n = 0; isdigit(*s); s++)
      n =10 *n + *s - '0';
   return sign * n;
}

void reverse(char *);

/* itoa : convert n to characters in s; pointer version */
void itoa(int n, char *s){
   int sign;
   char *t = s;        /* save pointer to s */
   if((sign = n) < 0)  /* record sign */
       n = -n;         /* make n positive   */
   do{                     /* generate digits in reverse order    */
     *s++ = n %10 + '0';     /* get next digit */
   } while((n /= 10) > 0);   /*delete it */
   if(sign < 0)
      *s++ = '-';
   *s = '\0';
   reverse(t);
}

#include <string.h>

/*reverse: reverse string s in place      */
void reverse(char *s){
   int c;
   char *t;

   for(t = s + (strlen(s) - 1); s < t; s++, t--){
         c = *s;
         *s = *t;
         *t = c;
   }
}

/*strindex: return index of t in s, -1 if none   */
int strindex(char *s, char *t){
    char *b = s;    /* beginning of string s */
    char *p , *r;
  
    for(; *s != '\0'; s++){
       for(p=s, r=t; *r != '\0' && *p == *r; p++, r++)
              ;
       if(r > t && *r == '\0')
            return s - b;
    }
    return -1;
}

#include <ctype.h>

/* atof: convert string s to double;pointer version   */
double atof(char *s){
     double val, power;
     int sign;

     for(; isspace(*s);s++)   /* skip white space */
             ;
     sign = (*s == '-') ? -1 : 1;
     if(*s == '+' || *s == '-')
          s++;
     for(val = 0.0; isdigit(*s); s++)
        val = 10.0 * val + (*s - '0');
     if (*s == '.')
          s++;
     for(power = 1.0 ; isdigit(*s);s++){
        val = 10.0 * val + (*s - '0');
        power *= 10.0;
     }
     return sign *val /power;
}

#include <stdio.h>
#include <ctype.h>

#define    NUMBER    '0'  /*signal that a number was found */

int getch(void);
void ungetch(int);

/*getop: get next operator or numeric operand; pointer version */
int getop(char *s){
    int c;

    while((*s =c =getch()) == ' ' || c == '\t')
             ;
    *(s + 1) = '\0';
    if (!isdigit(c) && c != '.')
         return c;              /* not a number */
    if(isdigit(c))         /*collect integer part */
       while(isdigit(*++s =c=getch()))
               ;
    if(c == '.')       /* collect fraction part */
       while(isdigit(*++s = c =getch()))
                ;
    *s = '\0';
    if (c != EOF)
          ungetch(c);
    return NUMBER;
}

Write the versions of the library functions strncpy, strncat, and strncmp, which operate on at most the first n characters of their argument strings. For e.g strncpy(s, t) copies at most n characters of t to s.

/*strncpy:copy n characters from t to s */
void strncpy(char *s, char *t, int n){
     while(*t && n-->0)
           *s++ = *t++;
     while(n-- > 0)
         *s++ = '\0';
}
/*strncat:concatenate n characters of t to the end of s */
void strncat(char *s, char *t, int n){
     void strncpy(char *s, char *t, int n);
     int strlen(char *t);

    strncpy(s + strlen(s), t, n);
}

/*strncmp ; compare at most n characters of t with s */
int strncmp(char *s, char *t, int n){
      for(; *s == *t; s++, t++)
        if (*s == '\0' || --n <= 0)
            return 0;
      return *s - *t;
}

Write the function strend(s ,t) , which returns 1 if the string t occurs at the end of the string s, and zero otherwise.

/*strend: return 1 if string t occurs at the end of s */
int strend(char *s, char *t){
    char *bs = s;   /*remember beginning of strs */
   char *bt = t;

   for(; *s; s++)  /*end of the string s */
         ;
  for(;*t; t++)   /*end of the string t */
         ;
  for(; *s == *t; s--, t--)
      if(t == bt || s == bs)
           break;   /* at the beginning of a str */
  if(*s == *t && t == bt && *s != '\0')
         return 1;
  else
       return 0;
}

Write getfloat, the floating point analog of getint.What type does getfloat return as its function value?

#include <stdio.h>
#include<ctype.h>

int getch(void);
void ungetch(int);

/*getfloat; get next floating-point  number from input */
int getfloat(float *pn){
    int c ,sign;
    float power;

    while(isspace(c =getch()))   /* skip white space */
          ;
    if(!isdigit(c) && c != EOF && c != '+' && c != '-' && c != '.'){
           ungetch(c);     /* it's not a number */
           return 0;
    }
    sign = (c == '-') ? -1 : 1;
    if (c == '+' || c == '-')
         c =getch();
   for(* pn = 0.0; isdigit(c); c =getch())
       *pn = 10.0 * * pn + (c - '0');  /* integer part */
   if (c =='.')
       c =getch();
   for(power = 1.0; isdigit(c); c =getch()){
      *pn = 10.0 * *pn + (c - '0');   /* fractional part */
      power *=10.0;
   }
   *pn *=sign /power;    
   if(c != EOF)
       ungetch(c);
   return c;
}

As written, getint treats a + or – not followed by a digit as a valid representation of zero. Fix it to push such a character back on the input.

#include <stdio.h>
#include <ctype.h>

int getch(void);
void ungetch(int);

/* getint: get next integer from input into *pn      */
int getint(int *pn){
     int c, d, sign;

     while(isspace(c =getch()))  /* skip white space   */
              ;
     if(!isdigit(c) && c != EOF && c != '+' && c != '-') {
          ungetch(c);     /* it's not a number */
          return 0;
     }
     sign = (c == '-') ? -1 : 1;
     if (c == '+' || c == '-') {
         d = c ;       /* remember sign char */
         if(!isdigit(c = getch())) {
            if (c != EOF)
                 ungetch(c);     /* push back non-digit */
            ungetch(d);         /* push back sign char  */
            return d;
         }
     }
     for(*pn = 0; isdigit(c); c =getch())
        *pn = 10 * *pn + (c - '0');
     * pn += sign;
     if (c != EOF)
           ungetch(c);
     return c;
}

Write a recursive version of the function reverse(s), which reverses the string s in place.

#include <string.h>

/*reverse: reverse string s in place    */
void reverse(char s[]){
     void reverse(char s[], int i, int len);
    
     reverse(s, 0, strlen(s));
}
/* reverse: reverse string s in place: recursive    */
void reverse(char s[], int i, int len){
    int c , j;

    j = len - (i + 1);
    if (i < j){
        c = s[i];
        s[i] = s[j];
        s[j] = c;
        reverse(s, ++i, len);
    }
}