K&R exercise 1-21

232 views Asked by At

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. When either a tab or a single blank would suffice to reach a tab stop, which should be given preference?

The code I wrote for the exercise:

#include <stdio.h>

#define TAB 8

void entab(int space);

int main()
{
    int c, i;

    i = 0;

    while ((c = getchar()) != EOF)
    {
        if (c == ' ')
            ++i;

        else if (c == '\t')
            i = i + TAB;

        else
        {
            entab(i);
            i = 0;
            putchar(c);
        }
    }

    return 0;
}

void entab(int space)
{
    int i;

    for (i = 1; space >= TAB; ++i)
        if (i == TAB)
        {
            putchar('\t');
            i = 0;
            space = space - TAB;
        }

    for (i = 0; i < space; ++i)
        putchar(' ');
}

But when I give it the input "3 blank spaces + a tab + 5 blank spaces + j" the output I get is longer than the input :

The first line in the picture is the input and the second line is the output

The first line in the picture is the input and the second line is the output

Update:

Rewrote the code based on one of the comments and one of the answers into this:

#include <stdio.h>

#define TAB 8

void entab(int space);

int main()
{
    int c, i, l;

    i = l = 0;

    while ((c = getchar()) != EOF)
    {
        ++l;

        if (c == ' ')
            ++i;

        else if (c == '\t')
            i = i + TAB - (l%8);

        else
        {
            entab(i);
            i = 0;
            putchar(c);
        }

        if (c == '\n')
            l = 0;
    }

    return 0;
}


void entab(int space)
{
    int i;

    for (i = 0; space >= TAB; ++i)
        if (i == TAB)
        {
            putchar('\t');
            i = -1;
            space = space - TAB;
        }

    for (i = 0; i < space; ++i)
        putchar(' ');
}

but now the problem is that it's always one characters less than the input: enter image description here

2

There are 2 answers

2
nischal sharma On

The output you are seeing is longer than the input because the program is replacing each space with a tab and some spaces. You should modify the entab function to replace strings of blanks with a tab followed by the appropriate number of spaces.

    #include <stdio.h>

#define TAB 8

void entab(int space);

int main()
{
    int c, i, l;

    i = l = 0;

    while ((c = getchar()) != EOF)
    {
        ++l;

        if (c == ' ')
            ++i;
        else
        {
            entab(i);
            i = 0;
            putchar(c);
        }

        if (c == '\n')
            l = 0;
    }

    return 0;
}

void entab(int space)
{
    int i, num_tabs, num_spaces;

    if (space == 0)
        return;

    num_tabs = space / TAB;
    num_spaces = space % TAB;

    for (i = 0; i < num_tabs; ++i)
        putchar('\t');

    for (i = 0; i < num_spaces; ++i)
        putchar(' ');
}
3
hansoko On

Couldn't fix the code above so I rewrote it entirely and methinks it works if anyone's interested:

#include <stdio.h>

#define TAB 8

int main()
{
    int i, c, l;

    i = l = 0;

    while ((c = getchar()) != EOF)
    {
        if (c == ' ')
        {
            ++i;
            if ((l%8 + i) == TAB)
            {
                putchar('\t');
                l = i = 0;
            }
        }
        

        else if (c == '\n')
        {
            putchar('\n');
            l = i = 0;
        }

        else if (c == '\t')
        {
            putchar('\t');
            l = i = 0;
        }

        else
        {
            ++l;

            while (i)
            {
                putchar(' ');
                --i;
                ++l;
            }

            putchar(c);
        }
    }

    return 0;
}