HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

K&R exercise 1-19: reversing each line of input

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
eachlineexerciseinputreversing

Problem

This is my solution for exercise 1-19 of K&R:


Write a function reverse(s) that reverses the character string s. Use it to write a program that reverses its input a line at a time.1

It works, but I'm trying to write good programs. I think the fact that I can't use the length of the vector when already got the line in function getlinea makes me think I could do better. The function reverse(s) uses 3 for sentences, which might be a little ugly. I know it doesn't mean it's not good but having to "read" the line 4 times is kind of a little stupid to me. I still can't think of a different solution.

/*
 * main.c
 *
 *  Created on: 19/3/2015
 *      Author: utnso
 */

#include 

#define MAXLINE 1000

void reverse (char s [] );
int getlinea (char s [] , int lim);

int main ()
{
    int len;
    char palabra [MAXLINE];
    while ( ( len = getlinea ( palabra, MAXLINE ) )  >= 0 )
        if (len > 0)
            printf ("%s\n", palabra);
    return 0;

}

int getlinea ( char s [], int lim )
{
    int i, c;
    i = 0;
    while ( ( c = getchar() ) != EOF && c != '\n' && i  0 )
        reverse ( s ) ;
    else
        if ( c == EOF )
            return -1;
    return i ;
}

void reverse ( char turnaround [] )
{
    int i, j;
    int h = 0;
    char aux [MAXLINE];
    for ( i = 0; turnaround [i] != '\0' ; ++i )
        ;
    for ( j = i-1 ; j >= 0 ; --j)
    {
        aux [h] = turnaround [j];
        ++h;
    }
    for ( i = 0 ; turnaround [i] != '\0' ; ++i )
        turnaround [i] = aux [i];
}


This is the output for

$ ./1-19 < main.c


(it also deletes white lines)

```
*/
c.niam *
*
5102/3/91 :no detaerC *
osntu :rohtuA *
/*
>h.oidts ) ) ENILXAM ,arbalap ( aenilteg = nel ( ( elihw
)0 > nel( fi
;)arbalap ,"n\s%"( ftnirp
;0 nruter
}
) mil tni ,][ s rahc ( aenilteg tni
{
;c ,i tni
;0 = i
) 1-mil i ( fi
{
;'0\' = ]i[ s
; ) s ( esrever
}
esle
) FOE == c ( fi
;1- nruter
; i nruter

Solution

-
getlinea does too much: it reads the line and reverses it. A Single Responsibility Principle mandates restructuring the code:

while((len = getlinea(...)) > 0) {
    reverse();
    print();
}


-
Avoid naked loops. Each loop represent an important action, and deserves a name. The code:

reverse(char turnaround[])
{
    char aux[...];
    int len = length_of_string(turnaround);
    copy_backwards(aux, turnaround, len);
    copy(turnaround, aux, len);
}


is much easier to reason about.

-
The length of the input is known to the caller. Consider passing it as parameter:

reverse(char turnaround[], int len)
{
    char aux[...];
    copy_backwards(aux, turnaround, len);
    copy(turnaround, aux, len);
}


-
Finally, a string can be reversed in place. There is no need for aux. I hope you can figure a solution yourself.

Code Snippets

while((len = getlinea(...)) > 0) {
    reverse();
    print();
}
reverse(char turnaround[])
{
    char aux[...];
    int len = length_of_string(turnaround);
    copy_backwards(aux, turnaround, len);
    copy(turnaround, aux, len);
}
reverse(char turnaround[], int len)
{
    char aux[...];
    copy_backwards(aux, turnaround, len);
    copy(turnaround, aux, len);
}

Context

StackExchange Code Review Q#84539, answer score: 8

Revisions (0)

No revisions yet.