Apurba Ghosh
Apurba Ghosh

Reputation: 33

Why is this C program printing line longer than MAXLINE?

The program should print all the input lines which length is longer than MINLINE 5 and shorter than MAXLINE 10. Ref. K&R book exercise 1.17

#include <stdio.h>
#define MAXLINE 10
#define MINLINE 5

int getlines(char lines[], int maxline);

int main()
{
    int length;
    char lines[MAXLINE];

    while ((length = getlines(lines, MAXLINE)) > 0)
    {
        if (length > MINLINE)
            printf("%s", lines);
    }
    return 0;
}

int getlines(char lines[], int maxline)
{
    int i, c;

    for (i = 0; i < maxline - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
    {
        lines[i] = c;
    }

    if (c == '\n')
    {
        lines[i] = c;
        ++i;
    }

    lines[i] = '\0';

    return i;
}

Desired outpur should be like this :-

Hello\n
Hello\n
hi\n
excuseMe\n
excuseMe\n
longLineNotToBePrinted\n
done
done

but unexpectedly the program printing lines that are far longer than MAXLINE and sometimes printing those omitting some trailing characters.

Upvotes: 0

Views: 125

Answers (2)

Apurba Ghosh
Apurba Ghosh

Reputation: 33

/* Updated code. Now it is working fine. Problems were both in main() function and in the function getlines().

#include <stdio.h>
#define MAXLINE 10
#define MINLINE 5

int getlines(char lines[], int maxline);

main()
{
    int length;
    char lines[MAXLINE];

    while ((length = getlines(lines, MAXLINE)) > 0)
    {
        if (length > MINLINE)
        {
/* As the input line can be longer than MAXLINE and in that case there will be no '\n' escape sequence to be stored in the lines[MAXLINE] array so we have used the if block to flow the control in such a way that when the input line is  longer than MAXLINE, the output string will be printed manually with a '\n' *newline character. */

            if (length > MAXLINE)
                printf("%s\n", lines);
            else
                printf("%s", lines);
        }
    }
    return 0;
}

int getlines(char lines[], int maxline)
{
    int i, j, c;
    i = 0;

    for (j = 0; (c = getchar()) != EOF && c != '\n'; ++j)
    {

/* In the for loop this time we didn't use the condition 'j < maxline
-1' as getchar() needs to read the whole input line no matter it's length(can be greater than MAXLINE), rather we have used the 'j < maxline -1' condition as a nested if block inside the for loop. While doing this to keep the getchar() function busy reaching the last input character no matter how long the line is we have used two variable i and j to overcome the problem in such a way that i will be used to store characters in the lines[MAXLINE] array, while j will be increased untill it reaches the end of the line. */

        if (j < maxline - 1)
        {
            i = j;
            lines[i] = c;
            ++i;
        }
    }

    if (c == '\n')
    {
        if (j < maxline - 1)
        {
            lines[i] = c;
            ++i;
            ++j;
        }
        else
            ++j;
    }

    lines[i] = '\0';

    return j;
}

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

For starters this function

int getlines(char lines[], int maxline)
{
    int i, c;

    for (i = 0; i < maxline - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
    {
        lines[i] = c;
    }

    if (c == '\n')
    {
        lines[i] = c;
        ++i;
    }

    lines[i] = '\0';

    return i;
}

has undefined behavior because it can store the character '\0' at position maxline that is outside the array lines that has the valid range of indices [0, maxline).

As for your question about the output then if you entered a text that is greater than maxline then the function will return a string that does not contain the new line character '\n'. So the next string will be outputted in the same line.

Upvotes: 1

Related Questions