Exercise 5-12-1 (detabn with command-line arguments)

Chapter_5     Exercise_5-11-2 Exercise_5-12-2







Exercise 5-12     K&R, p. 118


Exercise 5-12. Extend entab and detab to accept the shorthand
    entab -m +n
to mean tab stops every n columns, starting at column m. Choose convenient (for the user) default behavior.




CONTENTS:     tabs.txt     detabn.c




Note:  We decided to extend the program detab from Chapter_1 (and not from the previous_exercise) to keep it simpler and easier to understand. To simplify things even further, the program now works with only 2 command-line arguments.




tabs.txt         download


1234567 123456 12345 1234 123 12 1 0
a ab abc abcd abcde abcdef abcdefg h





detabn.c         download


#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#include <stdlib.h> // for atoi()

#define TAB 4 // 4 spaces
// For every chunk of TAB chars,
// detabn("abc\t") == "abc " // 1 space
// detabn("ab\t") == "ab " // 2 spaces
// detabn("a\t") == "a " // 3 spaces
// detabn("\t") == " " // 4 spaces

// we consider first column to be 1, just like first line is 1, not 0
void detabn(int col, int tab); // turn tabs into spaces
// use TAB before reaching column col, then use tab

int main(int argc, char *argv[])
{
if (argc != 3 || *argv[1] != '-' || *argv[2] != '+')
{
printf("Usage: ./detabn -m +n\n");
printf("m = column number, n = tab size\n");

return 1; // end program, signalling error
}

argv[1]++, argv[2]++; // move past '-' or '+'

int col = atoi(argv[1]);
int tab = atoi(argv[2]);

if (col <= 0 || tab <= 0)
{
printf("Usage: ./detabn -m +n\n");
printf("m = column number > 0, n = tab size > 0\n");

return 1; // end program, signalling error
}

detabn(col, tab);

return 0;
}

// use TAB before reaching column col, then use tab
void detabn(int col, int tab) // turn tabs into spaces
{ // col > 0, tab > 0
int c, i;
int chunk = 0; // count up to tab chars (next tab stop)
int count = 1; // count up to col-1 chars, start at column 1
// if col == 1, detabn(1, tab) is detab(tab)
int tabsize = TAB; // default value until count >= col
// starting at column col, tabsize = tab

if (count >= col) // if (count == col)
{
tabsize = tab;
// chunk = 0; // restart counting
}

while((c = getchar()) != EOF)
{
if (c == '\n')
{
chunk = 0; // reset, go to next line
count = 1; // reset to column 1
tabsize = TAB; // reset to default

if (count >= col) // if (count == col)
{
tabsize = tab;
// chunk = 0; // restart counting
}

putchar(c); // putchar('\n');
}
else if (c == '\t') // advance to next tab stop
{
for (i = 0; i < tabsize-chunk; i++)
{putchar(' ');} // add spaces up to next tab stop

if (count < col)
{
count += tabsize-chunk; // count added spaces

if (count >= col) // if (count == col)
{
tabsize = tab;
// chunk = 0; // restart counting
}
}

chunk = 0; // reset, go to next chunk of tabsize chars
}
else
{
putchar(c);
chunk++;

if (chunk >= tabsize) // if (chunk == tabsize)
{chunk = 0;} // reset, go to next chunk of tabsize chars

if (count < col)
{
count++;

if (count >= col) // if (count == col)
{
tabsize = tab;
chunk = 0; // restart counting
}
}
}
}
}
/*
gcc detabn.c -o detabn
./detabn
Usage: ./detabn -m +n
m = column number, n = tab size

./detabn 1 8
Usage: ./detabn -m +n
m = column number, n = tab size

./detabn -i +8
Usage: ./detabn -m +n
m = column number > 0, n = tab size > 0

./detabn -1 +-8
Usage: ./detabn -m +n
m = column number > 0, n = tab size > 0

./detabn -1 +8 // input from the keyboard
1234567 123456 12345 1234 123 12 1 0 // Enter (tabs)
1234567 123456 12345 1234 123 12 1 0 // spaces
// Ctrl^D or Ctrl^C in Linux, Ctrl^Z + Enter in Windows (EOF)

./detabn -1 +8 < tabs.txt
1234567 123456 12345 1234 123 12 1 0
a ab abc abcd abcde abcdef abcdefg h

./detabn -1 +8 < tabs.txt > spaces.txt

./detabn -5 +4 < tabs.txt
1234567 123456 12345 1234 123 12 1 0
a ab abc abcd abcde abcdef abcdefg h

./detabn -5 +7 < detabn.c // input from source file

./detabn -3 +4 < detabn // input from binary file
*/









Chapter_5     Exercise_5-11-2 BACK_TO_TOP Exercise_5-12-2



Comments

Popular posts from this blog

Contents

Blogger Page Margins in Contempo