Write a program that replaces tabs with the correct number of spaces. Assume a fixed number of tab stops, say every n columns. Should n be a variable or a symbolic parameter?

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; /* we will need this since string_b will not always be the same size as string_a.*/
  int original_number_of_chars = *number_of_chars;

  /* copy string_a into string_b */
  while(i < original_number_of_chars)
  {

    /* if the current letter is a tab(9). */
    if(string_a[i] == 9)
    {
      /* here's the tricky part. A "tab" is not just four or whatever spaces but a text-alignment
       * tool. We know every tab stop is equal to TAB_STOP_LENGTH which is what we have to align
       * our text to. So what we do is math. Our variable o indicates where we are in the string
       * so we can use this to determine how far away we are from the tab stop. 
       * EXAMPLE: 
       * if tab stop is 4 then our o value has to be cleanly divisible by 4. If it is not add
       * another space until it is and then you will have reached your tab-stop. 
       */
      /* modulus is, once again, our friend. No remainder means a clean division. */
      do
      {
        string_b[o] = L'.';
        if(o < MAX_STRING_LENGTH)
        {
          o++;
          *number_of_chars += 1;
        }
      } while(o % TAB_STOP_LENGTH != 0);

      /* make sure to move away from that nasty tab! */
      i++;
    }
    else
    {
      string_b[o] = string_a[i];
      o++;
      i++;
    }
  }
  /* printf("i=%i, o=%i\n", i, o); */

  /* make sure to end each string. */
  string_b[o] = '\n';

  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 tabs with spaces.\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");
        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 tabs with spaces.
--------------------------------------------------------------------
This    is      just    a       test.
--------------------------------------------------------------------
This....is......just....a.......test.
--------------------------------------------------------------------
Hello   test    !
--------------------------------------------------------------------
Hello...test....!
--------------------------------------------------------------------

Notes:

"n" is a FIXED number of tab-stop columns. Therefore it can be defined.
If "n" was VARIABLE you would ask for it's value and then store it in a int.