Learning
Learning

Reputation: 37

Why is this code printing a random character inbetween the input and output lines?

I'm trying to write a program (in C) where the input is reversed and printed in reverse line by line. For the most part, the code actually does just that. The trouble is that for some (most) of my input, I will get a random character or an extra newline in between my input and my output in the console.

For example, I start the program, type "testing" into the console, and get "gnitseT" back after hitting enter. This has happened successfully and is what I expect. It looks like this:


Testing

gnitseT


But then when I type "Hello" into the console, it looks like this:


Hello

g (unexpected)

olleH


Or if I type "running" into the console, instead of getting an unexpected "g" in between my input and output lines, I get an extra newline.


Running

newline here

extra newline here (unexpected)

gninnuR


#include <stdio.h>




void reverse(int length, char s[])
{
    int i;

    for (i = length; i >= 0; i--)
    {
        printf("%c", s[i]);
    }
    printf("\n");

}


int main(void)
{
    char smain[2000];
    int c;
    int i;

    i = 0;
    while ((c = getchar()) != EOF)
    {
        smain[i] = c;
        i++;
        if (c == '\n')
        {
            reverse(i, smain);
            i = 0;
        }
    }

    return 0;
}

The expected behavior is for the program to output into the console the reversed input after the enter key is pressed.

Sometimes, especially at the very beginning of the program, it will work perfectly.

Then, it starts giving me a random character in between my input and output, or it starts giving me an extra newline.

I would like to have it so that it just prints the input in reverse order without any unexpected odd characters showing up in between the input and the output.

Thanks for any help.

Upvotes: 1

Views: 1758

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84551

Your immediate problem is you are reading and attempting to print one character past the end of the characters stored in your array with

for (i = length; i >= 0; i--) {
    printf("%c", s[i]);
}

Why? You add length characters to smain in main(). In C, arrays are zero-based. The characters in your string are from 0 -> length-1 (the nul-character in a string is located at s[length], but here you never add a nul-terminating character, so the value at that index is simply indeterminate). If the element has not been initialized (which it will not be on your first word or any subsequent word equal to or longer than your longest word entered at that time) Undefined Behavior results since you are attempting to read and print an indeterminate value from an uninitialized element in array. How your terminal will output the indeterminate is undefined -- and may well result in a G being printed.

To correct the problem, loop for (i = length - 1; i >= 0; i++) or very simply:

while (length--)
    printf ("%c", s[length]);

putchar ('\n');     /* don't printf a single-character */

(note: don't call the variadic printf function to output a single-character, that is what putchar() is for)

Putting it altogether and fixing your logic so you don't add and print the '\n' as part of every word you are reversing, you could do:

#include <stdio.h>

#define MAXC 2048   /* if you need a constant, #define one (or more) */

void reverse(int length, char s[])
{
    while (length--)
        printf ("%c", s[length]);

    putchar ('\n');     /* don't printf a single-character */
}


int main (void) {

    char smain[MAXC];
    int c, i = 0;

    while ((c = getchar()) != EOF) {
        if (c == '\n') {
            reverse(i, smain);
            i = 0;
        }
        else
            smain[i++] = c;
    }
    if (i)  /* protect against file with no POSIX end-of-file */
        reverse (i, smain);

    return 0;
}

(note: the if {...} else {...} logic to prevent adding the '\n')

Example Use/Output

$ printf "Hello\nGoodbye\n" | ./bin/prnrevlines
olleH
eybdooG

Which will work just as well without the POSIX eof, e.g.

$ printf "Hello\nGoodbye" | ./bin/prnrevlines
olleH
eybdooG

Upvotes: 2

Omega 16
Omega 16

Reputation: 21

on line 29

++i;

this means "i" now have length+1 so, you have been out of the string, you can change the program to :

#include <stdio.h>




void reverse(int length, char s[])
{
    int i;

    for (i = length; i >= 0; i--)
    {
        printf("%c", s[i]);
    }
    printf("\n");

}


int main(void)
{
    char smain[2000];
    int c;
    int i;

    i = 0;
    while ((c = getchar()) != EOF)
    {
        smain[i] = c;
        if (c == '\n')
        {
            reverse(i, smain);
            i = 0;
        }
        else i++;
    }

    return 0;
}

Upvotes: 0

Related Questions