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

246 views Asked by At

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!

2

There are 2 answers

3
syntagma On BEST ANSWER

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.

2
Persixty On

Look closely at the line you mention:

while ((better_line_length(s, MAXLINE)) > 0) {

If the function better_line_length() returns 0 the condition is false and the loop ends. That's why it's giving up at the first blank line.

You should think about returning something different when you've really reached the end or just a blank line.

You might (for example) return -1 when you've reached the end of the input.