Reverse a string without the  header I'm learning C from the K.N. King book and just arrived at a question to reverse the words in a sentence.

Here is the output:


  Enter a sentence: you can cage a swallow can't you?
  
  Reversal of sentence: you can't swallow a cage can you?


Though I've done this and it runs correctly, I want to make my code shorter. I'm not asking for any other solution.

#include &lt;stdio.h&gt;

#define N 100

int main(void) {
  char ch[N], terminate;
  int i, j, k, len;
  printf("Enter a sentence: ");
  for(i = 0; i &lt; N; i++) {
    ch[i] = getchar();
    if(ch[i] == '?' || ch[i] == '.' || ch[i] == '!' || ch[i] == '\n') {
      len = i;        //Determine the length of the string
      terminate = ch[i];
      break;
    }
  }
  int word_count = 0;
  for(j = len - 1; j &gt;= 0; j--) {
    word_count++;
    if(ch[j] == ' ') {
      for(k = j+1; k &lt; len; k++) {
        printf("%c", ch[k]);
      }
      printf("%c", ch[j]);  // print space character
      len = len - word_count;
      word_count = 0;
    }

  }

  for(i = 0; i &lt; len; i++) {
    printf("%c", ch[i]);
    if(ch[i] == ' ') {
      break;
    }
  }
  printf("%c", terminate);

  return 0;
}


This can be done only with loops, arrays, getchar() and putchar() methoda using only &lt;stdio.h&gt; header and no extra header (restrict &lt;string.h&gt; header functions and methods). Also, no puts() and gets() functions. I guess this can be done only with two loops.
I have a few comments.


main takes argc/argv normally. Also start the function with the opening
brace in colum 0
Define one variable per line.
Your request for input might be better printed to stderr so that it can be
separated from program output.
Your initial loop should test for EOF. Currently it doesn't  You can test
this in the *NIX shell with (program is your executable):

/bin/echo -n "hello world" | ./program

terminate seems redundant
You can and perhaps should define loop variables in the loop (as long as
you don't need the value outside the loop):

for (int i = 0; i &lt; n; ++i) {

The second for-loop is a little messy.  For a start it has a nested loop -
my advice is to avoid nested loops and extract the inner loop to a function.
This is not always practical, but more often than not it is useful.  In this
case, you can write a little function (eg. print_chars) that prints a
specified number of characters.
Your terminating loop can be replaced by a call to the print_chars
function.
putchar is preferable to printf("%c", ...)
while, for, if etc should be followed by a space.
Testing for ' ' might be better done using isspace, which will test for
other space-like characters too.


Here is my version, for what it is worth:

#include &lt;stdio.h&gt;
#include &lt;ctype.h&gt;

#define N 100

static inline void print_chars(const char *s, long n)
{
    for (int i = 0; i &lt; n; ++i) {
        putchar(s[i]);
    }
}

int main(int argc, char **argv)
{
    char line[N];
    int ch; /* note that ch is an int to allow it to hold 'EOF' */
    int len = 0;

    fprintf(stderr, "Enter a sentence: ");

    while ((ch = getchar()) != EOF) {
        if (ch == '?' || ch == '.' || ch == '!' || ch == '\n' || len &gt;= N-1) {
            break;
        }
        line[len++] = (char) ch;
    }
    line[len] = '\0';

    char *end = line + len;
    char *s = end;
    while (--s &gt;= line) {
        if (isspace(*s)) {
            print_chars(s + 1, end - s - 1);
            putchar(*s);
            end = s;
        }
    }
    print_chars(line, end - line);
    if (ch != EOF) {
        putchar(ch);
    }
    return 0;
}