Write the function htoi(s), which converts a string of hexadecimal digits(including an optional x 0r 0X) into its equivalent integer value.The allowable digits are 0 through 9, a through f, and A through F.

#define    YES       1
#define    NO        0

/*htoi:convert hexadecimal string s to integer    */
int htoi(char s[]){
    int hexdigit, i, inhex, n;

    i =0;
    if (s[i]  == '0'){   /* skip optional 0x or 0X */
        ++i;
        if (s[i] == 'x' || s[i] == 'X')
             ++i;
    }
     n = 0;          /* integer value to be returned */
     inhex = YES     /*assume valid hexadecimal digit */
     for(; inhex == YES; ++i) {
          if (s[i] >= '0'  && s[i]  <= '9')
              hexdigit = s[i] - '0';
          else if (s[i] >= 'a' && s[i] <= 'f')
             hexdigit = s[i] - 'a' + 10;
          else if (s[i] >= 'A' && s[i] <= 'F')
            hexdigit = s[i]  - 'A' + 10;
          else
              inhex = NO;    /* not a valid hexadecimal digit */
          if (inhex == YES)
              n = 16 * n   + hexdigit;
     }
    return n;
}

Write a program to determine the ranges of char, short, int, and long variables ,both signed and unsigned, by printing appropriate values from standard headers and by direct computation.Harder if you compute them:determine the ranges of the various floating-point types.

#include <stdio.h>
#include <limits.h>

/*determine the ranges of types       */
int main(){
    /*signed types */
    printf("signed char min = %d\n", SCHAR_MIN);
    printf("signed char max = %d\n", SCHAR_MAX);
    printf("signed short min = %d\n", SHRT_MIN);
    printf("signed short max = %d\n", SHRT_MAX);
    printf("signed int min = %d\n", INT_MIN);
    printf("signed int max = %d\n", INT_MAX);
    printf("signed long min = %d\n", LONG_MIN);
    printf("signed long max = %d\n", LONG_MAX);
    /* unsigned types                                  */
    printf("unsigned char min = %u\n", UCHAR_MIN);
    printf("unsigned char max = %u\n", UCHAR_MAX);
    printf("usigned short min = %u\n", USHRT_MIN);
    printf("unsigned short max = %u\n", USHRT_MAX);
    printf("unsigned int min = %u\n", INT_MIN);
    printf("unsigned int max = %u\n", INT_MAX);
    printf("unsigned long min = %lu\n", ULONG_MIN);
    printf("unsigned long max = %lu\n", ULONG_MAX);
}

Write a program to check a C program for rudimentary syntax errors like unbalanced parentheses, brackets, and braces. Don’t forget about quotes, both single and double, escape sequences, and comments.(This program is hard if you do it in full generality.)

#include <stdio.h>

int brace, brack, paren;

void in_quote(int c);
void in_comment(void);
void search(int c);

/*rudimentary syntax checker for C programs     */
int main(){
    int c;
    extern int brace, brack, paren;

    while ((c =getchar()) != EOF) {
         if(c =='/'){
             if ((c =getchar()) == '*')
                    in_comment();    /*inside comment */
             else
                  search(c);
         }else if (c =='\' || c ==' " ')
               in_quote(c);    /* inside quote */
         else
              search(c);
        if (brace < 0){   /* output errors */
            printf("Unbalanced braces \n");
            brace = 0;
        }else if (brack < 0){
              printf("Unbalanced brackets \n");
              brack = 0;
        }else if ( paren < 0) {
               printf("Unbalanced parentheses\n");
               paren = 0;
        }
        if (brace > 0)   /*output errors */
              printf("Unbalanced braces\n");
        if (brack > 0)
             printf("Unbalanced brackets\n");
        if (paren > 0)
            printf("Unbalanced parentheses\n"); 
    }
   /* search: search for rudimentary syntax errors    */
   void search(int c) {
        extern int brace, brack, paren;
      if (c == '{')
           ++brace;
      else if (c ==' }')
           --brace;
       else if (c == '[')
           ++brack;
       else if (c == ']')
           --brack;
       else if (c == '(')
            ++paren;
       else if (c == ')')
            --paren;
   }
  /* in_comment: inside of a valid comment     */
 void in_comment(void){
      int c, d;
       c = getchar();    /*prev character */
       d = getchar();    /* curr character */
       while (c != '*' || d != '/'){   /* search for end */
           c = d;
           d = getchar();
       }
}

/*in_quote: inside quote              */
void in_quote(int c){
     int d;

     while((d =getchar()) != c)   /* search end quote  */
         if ( d == '\\')
               getchar();    /* ignore escape seq;
}
}

Write a program to remove all comments from a C program. Don’t forget to handle quoted strings and character constants properly. C comments do not nest.

#include <stdio.h>

void rcomment(int c);
void in_comment(void);
void echo_quote(int c);

/*remove all comments from a valid c program     */
int main(){
      int c, d;

      while((c =getchar()) != EOF)
           rcomment(c);
     return 0;
}
/*rcomment: read each character, remove the comments  */
void rcomment(int c){
     int d;

     if (c == '/')
        if ((d= getchar()) == '*')
              in_comment();       /* beginner comment */
        else if(d == '/')
              putchar(c);         /* another slash */
              rcomment(d);
        } else {
                putchar(c);
                putchar(d);
         }
    else if (c == '\' ' || c == ' '' ')
           ech0_quote(c);          /* quote begins */
    else
         putchar(c);        /* not a comment */
}
/* in_comment: inside of a valid comment */
void in_comment(void){
     int c, d;

     c = getchar();   /* prev character  */
     d = getchar();   /* curr character */
     while (c != '*' && d != '/'){  * search for end */
            c =d;
            d =getchar();
    }
}
/*echo_quote: echo characters within quotes */
void echo_quote(int c){
      int d;

       putchar(c);
       while((d =getchar()) != c) {  /*search for end */
             putchar(d);
             if (d == '\\')
                 putchar(getchar());   /* ignore escape seq */
       }
        putchar(d);
}

Write a program to “fold” long input lines into two or more shorter lines after the last nonblank character that occurs before the n-th column of input. Make sure your program that does something intelligent with very long lines, and if there are no blanks or tabs before the specified column.

#include <stdio.h>

#define      MAXCOL    10    /*maximum column of input */
#define      TABINC     8      /* tab increment size */

char line[MAXCOL];           /*input line            */
int exptab(int pos);
int findblnk(int pos);
void newpos(int pos);
void printl(int pos);

/*fold long input lines int two or more shorter lines  */
int main(){
     int c, pos;

      pos = 0;   /* position in the line */
      while((c =getchar()) != EOF){
           line[pos] = c;    /* store current character */
           if(c == '\t')    /* expand tab character */
               pos = exptab(pos);
            else if (c =='\n'){
                 printl(pos);    /*print current input line */
                 pos = 0;
            }else if (++pos >= MAXCOL) {
                   pos =findblnk(pos);
                   printl(pos);
                   pos = newpos(pos);
             }
      }
}
/*printl: print line until pos column            */
void printl(int pos){ 
     int i;
     for(i =0; i< pos; ++i)
         putchar(line[i]);
      if(pos > 0)     /*any chars printed?   */
         putchar('\n');
}
/*exptab: expand tab into blanks   */
int exptab(int pos){
    line[pos] = ' ';     /*tab is at least one blank */
    for(++pos; pos < MAXCOL && pos % TABINC != 0; ++pos)
         line[pos] = ' ';
    if (pos < MAXCOL)   /* room left in current line   */
        return pos;
    else{
          printl(pos);
          return 0;      /*reset current position */
   }
}
/* findblnk: find blank's position */
int findblnk(int pos){
    while(pos >0 && line[pos] != ' ')
           --pos;
    if(pos == 0)   /*no blanks in the line  */
        return MAXCOL;
    else        /* at least one blank */
      return pos + 1;    /*position after blank */
        
}
/*newpos: rearrange line into new position    */
int newpos(int pos){
     int i, j;

     if (pos <= 0 || pos >= MAXCOL)
          return 0;
     else{
          i = 0;
         for(j =pos; j < MAXCOL; ++j){
             line[i] = line[j];
             ++i;
         }
           return i;     /* new position in line    */
     }
}

Write a program entab that replaces strings by the minimum number of tabs and blanks to achieve the same spacing.Use the same tab stops as for detab.When either a tab or a single blank would suffice to reach a tab stop, which should be given preference?

#include <stdio.h>

#define TABINC       8    /*tab increment size */

/* replace strings of blanks with tabs and blanks    */
int main(){
      int c, nb, nt, pos;

      nb = 0;                 /* # of blanks necessary */
      nl =0;                 /* # of tabs necessary    */
      for (pos = 1; (c =getchar()) != EOF; ++pos)
           if (c == ' '){
              if (pos % TABINC != 0)
                    ++nb;                /* increment # of blanks */
              else{
                  nb = 0;       /*reset # of blanks */
                  ++nt;         /* one more tab     */
              }
           } else {
                 for(; nt > 0; --nt)
                      putchar('\t');   /*output tab(s)  */
                 if(c == '\t')    /* forget the blank(s)  */
                       nb = 0;
                 else            /* output blank(s) */
                     for (; nb > 0 ; --nb)
                           putchar(' ');
                putchar(c);
                if(c == '\n')
                     pos = 0;
                else if (c == '\t')
                      pos = pos +  (TABINC - (pos -1) % TABINC) - 1;
           }
}

write a program detab that replaces tabs in the input with the proper number of blanks to space to the next tab stop. Assume a fixed set of tab stops, say every n columns.Should n be a variable or a symbolic parameter?

#include <stdio.h>

#define TABINC    8      /*tab increment size */

/*replace tabs with the proper number of blanks   */
int main(){
    int c, nb, pos;

    nb =0;       /*number of blanks necessary */
    pos = 1;     /*position of character in line */
    while((c =getchar()) != EOF){
          if (c == '\t'){    /*tab character        */
               nb =TABINC - (pos  -1) % TABBINC;
               while(nb > 0){
                    putchar(' ');
                    ++pos;
                     --nb;
               }
          }else if (c == '\n') {   /* newline character */
                  putchar(c);
                  pos = 1;
          }else{   /* all other characters */
                putchar(c);  
                 ++pos;
             }
    }
}

Write a function reverse(s) that reverses the character string s. Use it to write a program that reverses its input a line at a time.

#include <stdio.h>
#define   MAXLINE    1000    /*maximum input line size */

int getline(char line[], int maxline);
void reverse(char s[]);

/*reverse input lines, a line at a time     */
int main(){
     char line[MAXLINE];     /*current input line */

     while(getline(line, MAXLINE) > 0){
          reverse(line);
          printf("%s", line);
     }
}
/* reverse: reverse string s                  */
void reverse(char s[]){
    int i, j;
    char temp;

    i = 0;
    while (s[i] != '\0')   /*find the end of  string s */
          ++i;
    --i;                  /*back off from '\0'   */
   if (s[i] == '\n')
        --i;            /*leave newline in  place */
   j = 0;
   while (j < i){
         temp = s[j];
         s[j] = s[i];    /*swap the characters */
         --i;
         ++j;
   }
}

Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines

#include <stdio.h>
#define MAXLINE      1000    /*maximum input line size */

int getline(char line[], int maxline);
int remove(char s[]);

/* remove trailing blanks and tabs, and delete blank lines */
int main(){
    char line[MAXLINE];      /*current input line */

    while (getline(line, MAXLINE) > 0)
         if (remove(line) > 0)
              printf("%s", line);
         return 0;
}
/*remove trailing blanks and tabs from character string s*/
int remove(char s[]){
     int i;

      i = 0;
      while(s[i] != '\n')   /*find newline character */
            ++i;
      --i;                /*back off from '\n'    */
     while(i >= 0 && (s[i] == ' ' || s[i] == '\t'))
          --i;
     if (i >= 0){   /*is it a non blank line? */
         ++i;
          s[i] = '\n';             /*put newline character back  */
          ++i;
          s[i] = '\0';          /* terminate the string */
          
      }
      return i;
}