Exercise 1-21 (entab - Spaces to tabs)
Chapter_1 Exercise_1-20 | Exercise_1-22 |
Exercise 1-21 K&R, p. 34
Exercise 1-21. 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 for detab (see Exercise_1-20). When either a tab or a single blank would suffice to reach a tab stop, which should be given preference?
entab.c download
#include <stdio.h> // for getchar(), putchar(), EOF
#define TAB 4 // 4 spaces
// For every chunk of TAB chars,
// trailing spaces [+'\t'] become '\t',
// [trailing spaces +] '\t' become '\t':
// entab(" ") == "\t" // 4 spaces
// entab(" \t") == "\t" // 3 spaces
// entab(" \t") == "\t" // 2 spaces
// entab(" \t") == "\t" // 1 space
// entab("a ") == "a\t" // 3 spaces
// entab("a \t") == "a\t" // 2 spaces
// entab("ab ") == "ab\t" // 2 spaces
// entab("abc ") == "abc\t" // 1 space
// entab("\t") == "\t"
// entab("a\t") == "a\t"
// entab("*a\t") == "*a\t" // '*' is not '\t',
// entab("**a\t") == "**a\t" // but can be ' '
int main()
{
int c, i;
int count = 0; // count up to TAB chars (next tab stop)
int spaces = 0; // consecutive trailing spaces until '\t' or TAB stop
// (chunk of TAB chars), spaces <= count
while((c = getchar()) != EOF)
{
if (c == '\n') // count < TAB
{
while (spaces > 0) // add trailing spaces at the end of line
{
putchar(' ');
spaces--;
} // here spaces == 0
count = 0; // reset, go to next line
putchar(c); // putchar('\n');
}
else if (c == '\t') // advance to next TAB stop, count < TAB
{ // replace ([trailing spaces +] '\t') with '\t':
spaces = count = 0; // reset, go to next chunk of TAB chars
putchar(c); // putchar('\t');
}
else if (c == ' ')
{
spaces++;
count++;
if (count >= TAB) // if (count == TAB)
{ // replace trailing spaces with '\t'
putchar('\t');
spaces = count = 0; // reset, go to next chunk of TAB chars
} // else continue;
}
else
{
while (spaces > 0) // add trailing spaces before char
{
putchar(' ');
spaces--;
} // here spaces == 0
putchar(c);
count++;
if (count >= TAB) // if (count == TAB)
{count = 0;} // reset, go to next chunk of TAB chars
}
}
return 0;
}
/*
gcc entab.c -o entab
./entab // input from the keyboard
// For TAB == 8 on my computer (blanks or spaces separate the numbers):
1234567 123456 12345 1234 123 12 1 0 // Enter (spaces)
1234567 123456 12345 1234 123 12 1 0 // tabs
// Ctrl^D or Ctrl^C in Linux, Ctrl^Z + Enter in Windows (EOF)
./entab < entab.c // input from source file
./entab < entab // input from binary file
*/
Notes:
trailing spaces [+'\t'] means
trailing spaces or
trailing spaces + '\t'
(the argument in square brackets is optional).
We replace one trailing space with tab:
// entab("abc ") == "abc\t" // 1 space
because we may remove chars later and we may want to retain the same spacing.
Thus, we may delete 'c' and remain with
"ab\t" with the same spacing.
Chapter_1 Exercise_1-20 | BACK_TO_TOP | Exercise_1-22 |
Comments
Post a Comment