Aaron Walker
Aaron Walker

Reputation: 185

Getc() reading \n improperly

I am creating a program that prints each line of a file one by one in reverse word order. i.e. "The big black moose" prints as "moose black big The".

However, in the code below, it does not print the last word of lines that do not have a delimiter before the line break. A delimiter in this case is defined as any whitespace character such as space or tab.

int main(int argc, char const *argv[]) {
    if (argc != 2) return 0;

    int i = 0, c;
    int isD = 0, wasD = 1;
    int count = 0;

    FILE *file = fopen(argv[1], "r");

    while ((c = getc(file)) != EOF) {
        isD = c == ' ' || c == '\t' || c == '\n';

        if (!isD) {
            chars[i++] = c;
            count++;
        }

        if (isD && !wasD) {
            shiftInsert(i++, count);
            count = 0;
        }

        wasD = isD;
    }
    fclose(file);

    return 0;
}

int shiftInsert(int length, int shift) {
    int word[shift+1], i;

    printf("\n----------\nL:%d,S:%d\n", length, shift);

    for (i = 0; i < shift; i++)
        word[i] = chars[length-shift+i];
    word[shift] = ' ';

    for (i = 0; i < shift; i++)
        printf("%c", word[i]);

    for (i = length; i >= 0; i--)
        chars[i+shift+1] = chars[i];

    for (i = 0; i <= shift; i++)
        chars[i] = word[i];

    printf("|");
}

Upvotes: 0

Views: 322

Answers (2)

M Oehm
M Oehm

Reputation: 29126

This happens, because you don't enter the loop when getc finds the end of the file. If wasD is false, you'll have one unprocessed word in the buffer.

You could treat EOF as whitespace and place the terminating condition at the end of the loop:

do {
    c = getc(file);
    isD = (c == ' ' || c == '\t' || c == '\n' || c == EOF);

    // ...

} while (c != EOF);

This works, because you use the value of c only if it is not a delimiter. (The special value EOF is outside the valid range of (unsigned) chars and should not be inserted into strings or printed.)

Upvotes: 1

TonyB
TonyB

Reputation: 947

stdout is not getting flushed because your last output didn't contain a newline...

Change this line

printf("|");

to

printf("|\n");

Upvotes: 0

Related Questions