HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Replacing strings of blanks by tabs and blanks to achieve same spacing

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
sameblanksandachievereplacingtabsstringsspacing

Problem

#include 

#define MAXLINE 1000    /* Maximum length of a line */
#define TABSTOP 4       /* Length of tabstop */

int getLine(char line[], int limit);
int lookAhead(char line[], int start, int end);

    /*
     * 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.
     */

int main(void)
{
    int tabIndex, i;
    char line[MAXLINE];

    while ((getLine(line, MAXLINE)) > 0) {
        i = 0;
        while (line[i] != '\0') {
            if (line[i] == ' ') {
                tabIndex = i + (TABSTOP - (i % TABSTOP)); 
                if ((lookAhead(line, i + 1, tabIndex)) == 1) {
                    putchar('\t');
                    i = tabIndex;
                } else {
                    putchar(line[i]);
                    ++i; 
                }
            } else {
                putchar(line[i]);
                ++i;
            }
        }
    }
    return 0;
}

int getLine(char line[], int limit)
{
    int inputVal, i;

    for (i=0; i < (limit - 1) && (inputVal = getchar()) != EOF &&
            inputVal != '\n'; ++i) {
        line[i] = inputVal;
    }
    if (inputVal == '\n') {
        line[i] = inputVal;
        ++i;
    }
    line[i] = '\0';
    return i;
}

int lookAhead(char line[], int start, int end)
{
    int i, clearPath;

    clearPath = 1;
    for (i = start; i < end; ++i) {
        if (line[i] != ' '){
            clearPath = 0;
        }
    }
    return clearPath;
}

Solution

I don't think a proper getline() function should return an int, whether it's based on the attempted read (a boolean) or something else.

I believe you're trying to imitate fgets(), which instead returns a char* (the extracted file line) if the read was successful or NULL if it failed. A proper I/O function should set an error flag upon a failed read attempt, and this is not done by returning an int. Plus, there will be issues if the caller of your function expects a string or a failbit, which should be the case if the caller expects proper feedback.

Unless fgets() really doesn't satisfy your needs here, I'd recommend using that or another library function that handles this properly. Recreating an I/O function can cause problems if not written carefully, and even then you shouldn't be doing that.

Context

StackExchange Code Review Q#51702, answer score: 3

Revisions (0)

No revisions yet.