2

For the below question,

Exercise 12336 - Read ordinary text a character at a time from the program's standard input, and print it with each line reversed from left to right. Read until you encounter end-of-data`

You may wish to test the program by typing`

      prog5rev | prog5rev

to see if an exact copy of the original input is recreated. To read characters to end of data, use a loop such as either`

   char ch;
   while( ch = getchar(), ch >= 0 ) /* ch < 0 indicates end-of-data */
    or
    char ch;
    while( scanf( "%c", &ch ) == 1 ) /* one character read */

Here is my solution:

#include  <stdio.h>

void f(char *);
int main(void)
{
    char ch = getchar();
    f(&ch);

    return 0;
}

void f(char *ch){
    if(*ch < 0)
        return;
    else{
        char character = getchar();
        f(&character);
    }
    putchar(*ch);
}

Input:

abc | abc

Output:

cba | cba

Question:

The problem says: print it with each line reversed from left to right.

Is this solution correct?

overexchange
  • 15,768
  • 30
  • 152
  • 347
  • 2
    In the stipulation, I think `prog5rev` is the name of the program, not the sample input. They suggest running the program twice (with results of one piped to the other), and supplying some other input, and expecting the output to be the same as the input because it was reversed twice. You seem to have misinterpreted this as meaning to type `|` in the program input. – M.M Oct 13 '16 at 01:52

3 Answers3

1

That's such a clever solution that I really hate to break it, but using the stack for it has some limits. memory limits to be exact. If you have more than a certain, relatively small amount of input it will reach the limits and crash in one way or the other, e.g.: a segmentation fault. All 5,560,737 characters of the complete Shakespeare from Gutenberg does not pass, it segfaults at character 654,337.

You need to use the heap for larger input, sorry.

deamentiaemundi
  • 5,502
  • 2
  • 12
  • 20
0

Yes, this works as expected.

You read in a character and call f. If an EOF was not read, call f again then print the character read. Because you print the character after the recursive call, the characters print in the reverse order.

One change you should make however is to use int instead of char for the datatype. The getchar function returns an int so that an EOF can be properly detected. The putchar function accepts an int so there's nothing you need to worry about there.

Also, there's no need to pass the address of the variable that was read into since the calling function isn't changing it. You can simple pass the variable's value and change the function accordingly.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

The problem's statement already gives a hint about the solution:

   char ch;
   while( ch = getchar(), ch >= 0 ) /* ch < 0 indicates end-of-data */
    or
    char ch;
    while( scanf( "%c", &ch ) == 1 ) /* one character read */

You must use a loop to read data from stdin and then, inside the loop, tests if there is a new line and then, only then, print that line from right to left (revert the string).

The following is a code thata complishes the task in a simple way, it may need some improvement but it works.

Please, read the comments and try to understand what is going on there, if you have any questions please ask them.

#include <stdio.h>
#include <string.h> // for memset

void f(char *, int);

int main(void)
{
    char ch;
    char buffer[1024] = { 0 }; // 1024 = max supported line length
    int i; // ieterator

    i = 0;
    while( scanf( "%c", &ch ) == 1 ) { // while there is input
        if ( ch == '\n' ) { // if there is a new line
            f(buffer, i); // print the line (inverted)
            i = 0; // reset iterator
            memset(buffer, 0, 1024); // reset buffer
        } else {
            buffer[i++] = ch; // append read char to the buffer
        }
    }

    return 0;
}

void f(char *str, int n) {
    // just print from right to left (easier than reversing and then printing the string)
    while (n >= 0) {
        putchar(str[n]);
        n--;
    }
    putchar('\n');
}

Update: The book recommends to test the program using

 prog5rev | prog5rev

I recommend creating an input file and then running:

 $ prog5rev < input.txt | prog5rev

The previous statement assumes you are using linux (or some unix).

Example:

[ichramm@wilderjager][~]$ cat input.txt 
hello
world
[ichramm@wilderjager][~]$ ./test < input.txt  
olleh
dlrow
[ichramm@wilderjager][~]$ ./test < input.txt | ./test 
hello
world
ichramm
  • 6,437
  • 19
  • 30
  • 1
    Please do not do his entire homework assignment ... guide and answer pointed questions sure but giving away the whole enchilada is not helping him learn how to think which is the point of practice – Scott Stensland Oct 13 '16 at 02:17
  • @ScottStensland Are you serious? The rules are clear about this: The answer must be complete. So you downvote if the answer is not complete and also downvote if the answer is too complete? Make your mind! – ichramm Oct 13 '16 at 13:29