Page 118

Modify the programs entab and detab (written as exercises in Chapter 1) to accept a list of tab stops as arguments. Use the default tab settings if there are no arguments.

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

#define DEFAULT_TAB_STOP 4

int main(int argc, char *argv[])
{
	int c, i;
	int tab_pos = 0;
	int nb = 0;

	unsigned tab_stop = DEFAULT_TAB_STOP;
	if (argc > 1) {
		for (i = 0; isdigit(argv[1][i]); i++)
			;
		if (argv[1][i] != '\0') {
			printf("First argument must be an integer!\n");
			return 1;
		}
		tab_stop = atoi(argv[1]);
	}

	while ((c = getchar()) != EOF) {
		++tab_pos;
		tab_pos %= tab_stop;

		if (c == ' ') {
			nb++;
			if (tab_pos == 0) {
				if (nb > 1) {
					putchar('\t');
				} else {
					putchar(' ');
				}
				nb = 0;
			}
		} else {
			for (int i = 0; i < nb; i++) {
				putchar(' ');
			}

			nb = 0;
			if (c == '\n') {
				tab_pos = 0;
			}

			putchar(c);
		}
	}
}