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

Source:

#include "stdio.h"
#include "wchar.h"

#define MAX_STRING_LENGTH 1024

/* how big is our tab? */
#define TAB_STOP_LENGTH  8

typedef signed char bool;
#define TRUE  1
#define FALSE 0

int clear_string(wchar_t input_string[MAX_STRING_LENGTH])
{
  int i;

  for(i=0; i < MAX_STRING_LENGTH; i++)
  {
    input_string[i] = 0;
  }

  return 0;
}


int copy_string(wchar_t string_a[MAX_STRING_LENGTH], int *number_of_chars, wchar_t string_b[MAX_STRING_LENGTH])
{
  int i = 0;
  int o = 0;
  int original_number_of_chars = *number_of_chars;
  char mask[original_number_of_chars];

  /* since the tab stop detection code I wrote didn't work reliably lets try masking. */
  /* first create the mask. */
  for(i=0; i < original_number_of_chars; i++)
  {
    if(string_a[i] != L' ')
    {
      mask[i] = '_';
    }
    else
    {
      mask[i] = 'x';
    }
  }
  printf("\n");

  /* pass two will indicate the beginning of tab stops. */
  for(i=0; i < original_number_of_chars; i++)
  {
    if(((i % TAB_STOP_LENGTH) == 0) && (mask[i-1] == 'x'))
    {
      mask[i-1] = 'y';
    }
  }
  
  /* set the tab locations in the mask. */
  for(i=original_number_of_chars; i >= 0; i--)
  {
    /* find a tab */
    if(mask[i] == 'y')
    {
      /* move to the next letter. */
      i-=1;

      /* locate the disposable space. */
      while(mask[i] == 'x')
      {
        mask[i] = 'y';
        i-=1;
      }

      /* then increment up to the last space mask and replace it 
       * with a '!'.*/
      i+=1;
      mask[i] = '!';
    }
  }

  /* test the mask */
  for(i=0; i < original_number_of_chars; i++)
  {
    printf("%c", mask[i]);
  }
  printf("\n");
  
  /* printf("\nnumber of chars == %i\n", *number_of_chars); */

  /* now we know where to start at the end of the b string
   * so we can copy a to b. */
  o = 0;
  i = 0;

  while(i <= original_number_of_chars)
  {
    while(mask[i] == 'y')
    {
      i+=1;
    }
    /* if you find a tab. */
    if(mask[i] == '!')
    {
      /* insert the tab into the string. */
      string_a[i] = L'\t';
    }
    /* if you find a blank that must be saved. */
    if(mask[i] == 'x')
    {
      /* insert a '.' into the string. */
      string_a[i] = ' ';
    }

    string_b[o] = string_a[i];

    /* deincrement o and i. */
    o+=1;
    i+=1;
  }

  /* add one and properly end the string. 
  *number_of_chars += 1;
  string_b[*number_of_chars-1] = '\0';
  */

  return 0;
}

int main(int argc, char *argv[])
{
  int i = 0;
  int o = 0;
  int string_length = 0;

  wchar_t c;
  wchar_t input_string[MAX_STRING_LENGTH] = {0};
  wchar_t stored_string[MAX_STRING_LENGTH] = {0};

  bool running = TRUE;
  bool get_sentence = TRUE;


  printf("Please enter a string with a max length of %i.\n[ctrl]+[d] to exit.\n", MAX_STRING_LENGTH);
  printf("I will replace your spaces with tabs where I can.\n");
  printf("Please do not enter tabs.\n");
  printf("--------------------------------------------------------------------\n");

  while(running)
  {
    while(get_sentence)
    {
      c = getwchar();

      if(c == EOF)
      {
        get_sentence = FALSE;
        running = FALSE;
        break;
      }
      if(c == L'\n')
      {
        get_sentence = FALSE;

        string_length = i;

        /* store our string. */
        copy_string(input_string, &string_length, stored_string);

        /* print it.
         *
         * note: I could not get wprintf to work at all so I'm just using a loop.
         *
         */
        printf("--------------------------------------------------------------------\n");
        for(i=0; i <= string_length; i++)
        {
          printf("%lc", stored_string[i]); 
        }
        printf("\n--------------------------------------------------------------------\n");
        string_length = 0;

        /* clear the strings */
        clear_string(input_string);
        clear_string(stored_string);

        break;
      }
      

      input_string[i] = c;
      i++;
    }

    /* reset our counter. */
    i=0;

    /* Get another sentence. */
    if(running)
    {
      get_sentence = TRUE;
    }
  }

  return 0;
}

Output:

Please enter a string with a max length of 1024.
[ctrl]+[d] to exit.
I will replace your spaces with tabs where I can.
Please do not enter tabs.
--------------------------------------------------------------------

____x__!!yyyyyyy!yyyyyyyxxx____!!yyyyyyyxxx_!yyy!yyyyyyyx_____
--------------------------------------------------------------------
This is			   just		   a		 test.
--------------------------------------------------------------------

Notes:

I chose to give the tab preference since it is in fact a space-to-tab converion program.