Exercise 1.22 - fold long lines

Question

Write a program to fold long input lines into two or more shorter lines after the last non-blank character that occurs before the n-th column of input. Make sure your program does something ntelligent with very long lines, and if there are no blanks or tabs before the specified column.

Solution

/* fold, to fold long lines after a specified Column */

#include<stdio.h>

#define MAXCOL 50
#define TABVAL 8

char line[MAXCOL];
int expandtab(int pos);
int printline(int pos);
int getblank(int pos);
int newposition(int pos);

int main(void)
{
    int pos,c;
    pos = 0;

    while((c=getchar())!=EOF)
    {
        line[pos] = c;

        if( c == '\t')
            pos = expandtab(pos);
        if( c == '\n')
        {
            printline(pos);
            pos = 0;
        }
        else if( ++pos >= MAXCOL )
        {
            pos = getblank(pos);
            printline(pos);
            pos = newposition(pos);
        }
    }
    return 0;
}

int expandtab(int pos)
{
    line[pos] = ' ';

    for(++pos; (pos < MAXCOL)&&((pos % TABVAL)!= 0); ++pos)
    line[pos] = ' ';

    if( pos >= MAXCOL)
    {
        printline(pos);
        return 0;
    }
    else
        return pos;
}

int printline(int pos)
{
    int i;
    for(i = 0; i < pos; ++i)
        putchar(line[i]);
    if( pos > 0)
        putchar('\n');
}

int getblank(int pos)
{
    if( pos > 0)
        while( line[pos] != ' ')
            --pos;
    if(pos == 0)
        return MAXCOL;
    else
        return pos + 1;
}
int newposition( int pos)
{
    int i,j;

    if(pos <= 0 || pos >= MAXCOL)
        return 0;
    else
    {
        i = 0;
        for(j=pos;j < MAXCOL; ++j,++i)
        line[i] = line[j];  
    }
    return i;
}
    

    
Run this

Explanation

  1. We determine the column to fold in the MAXCOL variable.

2. Since tab character can occur too and folding a tab character means folding it in mid-way, we also replace the tabs in the line with spaces.

3. Every character of the file is filled into a line[MAXCOL] array and that line is acted upon by the program.

4. We start at pos=0 and take each character and place it in line[pos] and then we analyze the character to act upon the condition.

6. If the character is \t. We go and expand the tab character in the line[pos] and get newposition. So, when line[t] at pos = 0, it will be now line[' ', ' ', ' ',' ',' ',' ',' ',' '] and pos = 8

7. If character is \n then we print the entire line contents reset the pos back to 0.

  1. otherwise, we get into our program.

When we are folding, we should not be folding in between the word. So we have to track the previous space occuring in a line. The logic follows.

1. When our position is greater than MAXCOL, then we look for previous blank space by using getblank and we get the position of that blank.

2. We then fold, getblank will return the pos which is not greater than MAXCOL. So, the print the characters we have in line and then print newline.

3. We determine the new position based the return value of getblank. If the return value of getblank was greater than MAXCOL, then our new position is 0, which is a newline. We will replace the contents of line starting from 0, mark this as i, and place the folded contents by the last for loop in the program and after placing the folded contents we return the new value of i, which is our updated pos.

With our new position we continue with the rest of the program.

Comments by Disqus