Search code examples
ckernighan-and-ritchie

Unexpected Output for K&R Exercise 1-18 (The C Programming Language)


I am rather new to programming so please bear with me.

Here is the prompt for exercise 1-18: Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.

And here is my code:

#include <stdio.h>

#define MAXLINE 1000

int better_line_length(char line[], int lim);
void copy(char to[], char from[]);

int main(void)
{
    int len, a;
    char s[MAXLINE];
    char better_s[MAXLINE];

    while ((better_line_length(s, MAXLINE)) > 0) {
            copy(better_s, s);
            printf("%s\n", better_s);
        }

    return 0;
}

int better_line_length(char s[], int lim)
{
    int c, i, last_letter = 0;

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
        s[i] = c;
        if (c != ' ' && c != '\t')
            last_letter = i+1;
    }
    if (c == '\n' && s[0] == c)
        last_letter = 0;

    s[last_letter] = '\0';

    return last_letter;
}

void copy(char to[], char from[]) 
{
    int i = 0;

    while ((to[i] = from[i]) != '\0')
        ++i;
}

My program is not giving me the output I expect. It properly removes trailing blanks and tabs in the absence of a blank line, but things get weird when a blank line is present.

For example, if my input is (where ▯▯▯ are spaces)

abcdefg▯▯▯▯▯▯▯▯▯▯▯▯
1234▯▯▯▯▯

I get the expected output of

abcdefg
1234

But if my input is something like

abcdefg▯▯▯▯▯▯▯▯▯▯▯▯
1234▯▯▯▯▯

xyz▯▯▯▯▯▯
987▯▯▯▯▯

I get an output of

abcdefg
1234

But I expect an output of

abcdefg
1234
xyz
987

It seems like my while statement, while ((better_line_length(s, MAXLINE)) > 0) in main() stops executing when it encounters a blank line instead of just skipping over it. I've spent hours on this and I still can't figure out why. I thought that setting better_line_length to return 0 if the first character of a line is '\n' would fix the code, but it doesn't change a thing.

Why am I encountering this unexpected output, and why doesn't the above idea fix my program?

Please remember that K&R doesn't introduce certain advanced topics until much past chapter 1, so pointers and certain other topics do not yet make sense to me.

Thanks!


Solution

  • I see you are still trying to solve this exercise. Good for you, don't give up!

    As for problems with your current solution: one thing you can do is you can modify the better_line_length() function to return something meaning there was an empty line and skip that line inside the while ((len = better_line_length(s, MAXLINE)) > 0) loop.

    For example, you can add the following inside the body of better_line_length(), right after the for loop:

    if(i == 0 && c == '\n')
      return -1;
    

    Then you will know that this is the line you need to skip. You could also add similar return code meaning that there was end of file/end of stdin.

    Let me know if you need any more help.