0

Been working on K&R exercise 1-19:

Write a program that reverses its input a line at a time.

Wrote the following program:

#include <stdio.h>
#define MAXLINE 1000

main () {
    int c, x, y, z;
    char ip[MAXLINE];
    char ln[MAXLINE];
    char rv[MAXLINE];

    for (x = 0;(c=getchar()) != EOF; ++x)       
        ip[x] = c;

    for (x = 0; ip[x] != '\0'; ++x) {               
        for (y = 0; ip[x] != '\n'; ++y) {           
            ln[y] = ip[x];
            ++x;
        }

        for (z = 0; y != -1; ++z) {                 
            rv[z] = ln[y];
            --y;
        }
        printf("%s\n", rv);                         
    }
}

My problem is that this program's output is wildly inconsistent; given the same (multiple line) input, sometimes it will print each line in reverse with an added leading blank space , sometimes it will only reproduce the first line in reverse followed by blank lines, sometimes it prints garbage, and sometimes I just get an error message.

Has anybody run into this kind of volatility before without changing their code? How do I fix it?

Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
  • You posted quite a lot of related questions last time. Please consider using a different (and more recent - C has evolved a lot since K&R last updated) book and/or tutorial. stack overflow is not a tutorial site. – too honest for this site Feb 24 '16 at 23:54
  • 2
    Consider this, in your second loop, you test for null characters in `ip`. Did you set the null character when you read that in? – Jeff Mercado Feb 24 '16 at 23:55
  • 2
    You're reading the entire input into a 1000 byte buffer, without checking whether the input is more that 1000 bytes. You didn't `'\0'` terminate the `ip` string, yet the `x` loop looks for `ip[x] != '\0'`. And you didn't put a `'\0'` at the end of the `rv` string, which means that `printf` will run past the end of the string. – user3386109 Feb 25 '16 at 00:15
  • strongly suggest only reading a single line at a time to process. This means the first for() loop needs to be also checking for `\n` to find the end of the line. And that same loop needs to be checking the number of characters in the line so the input buffer is not overflowed. – user3629249 Feb 25 '16 at 03:00
  • in C, there are only a very few valid signatures for `main()` All of them have return type and (unless working on a bare metal machine with no OS, that return type will be `int` – user3629249 Feb 25 '16 at 03:01
  • when writing code: 1) follow the axiom: *only one statement per line and (at most) one variable declaration per statement.* 2) use meaningful variable names. I.E. names that indicate usage or content (or better) both. – user3629249 Feb 25 '16 at 03:03
  • interesting question! Alas no answer. I also encoutered similar problem in while loop matching against eof and \n. same input yet different result. – Tanzin May 16 '22 at 14:13

1 Answers1

0

If you're doing K & R, I would recommend you to buy the "C Answer Book", which has all the answers to it's excercises.

Try this:

#include <stdio.h>

#define MAX_LINE 1024

void discardnewline(char s[])
{
  int i;
  for(i = 0; s[i] != '\0'; i++)
  {
    if(s[i] == '\n')
      s[i] = '\0';
  }
}

int reverse(char s[])
{
  char ch;
  int i, j;

  for(j = 0; s[j] != '\0'; j++)
  {
  }

  --j;

  for(i = 0; i < j; i++)
  {
    ch   = s[i];
    s[i] = s[j];
    s[j] = ch;
    --j;
  }

  return 0;
}

int getline(char s[], int lim)
{
  int c, i;

  for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
  {
    s[i] = c;
  }

  if(c == '\n')
  {
    s[i++] = c;
  }

  s[i] = '\0';

  return i;

}

int main(void)
{
  char line[MAX_LINE];

  while(getline(line, sizeof line) > 0)
  {
    discardnewline(line);
    reverse(line);
    printf("%s\n", line);
  }
  return 0;
}

Some part of it is from the book, but I have even done my own modifications.

Box Box Box Box
  • 5,094
  • 10
  • 49
  • 67