# 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.