Reputation: 37
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
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
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