0

I'm trying to reverse a string word by word in C. So far, I succeeded in reversing words, but there is a new line issue I don't understand why happening. The code is below.

#include <stdio.h>
void reverse_string(char input[], int start, int end)
{
    char temp;
    while (start < end)
    {
        temp = input[start];
        input[start] = input[end];
        input[end] = temp;
        start++;
        end--;
    }
}
int main()
{
    char input[100];
    printf("Input > ");
    fgets(input, 100, stdin);
    int start = 0, end = 0;
    while (input[end])
    {
        for (end = start; input[end] && input[end] != ' '; end++);
        reverse_string(input, start, end - 1);
        start = end + 1;
    }
    printf("%s", input);
    return 0;
}

If an input is "Today is a sunny day.", The result would be

yadoT si a ynnu
.yad

What I want is

yadoT si a ynnu .yad

How should I edit the code above so that every reversed word will be on the same line?

  • 4
    [`fgets`](https://en.cppreference.com/w/c/io/fgets) include the newline in the buffer. See [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input) – Some programmer dude May 09 '22 at 09:32
  • 1
    Read this: https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input – Jabberwocky May 09 '22 at 09:33
  • Okay, solved in seconds, thanks to both Some programmer dude and Jabberwocky. –  May 09 '22 at 09:43

1 Answers1

0

As mentioned in the comments, the string returned by the call to fgets will include the terminating newline character. As that newline isn't an actual space character, it is considered part of the last word. To deal with this, you could remove that newline, as indicated in the linked posts.

Alternatively (and maybe much more simply), just change your input[end] != ' ' test to one that checks for any whitespace character(s); the isspace() function (declared in the "ctype.h" header file) will do this for you. So, just change that one-line (empty) for loop to this:

for (end = start; input[end] && !isspace((unsigned char)input[end]); end++) {}

Note that I have changed your "null statement" ; loop body to {}, which makes it much clearer to any future readers of your code that you actually intended that empty loop body, rather than making a typo-style error; it also prevents warnings on some compilers. Also, on why I used the (unsigned char) cast on the argument to isspace, see: Do I need to cast to unsigned char before calling toupper(), tolower(), et al.?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83