Re: Small Correction to K&R Exercise 1-22 Solution on CLC-Wiki
- From: "Mike S" <mgspross@xxxxxxxxxxxx>
- Date: 19 May 2006 08:32:09 -0700
Netocrat wrote:
Mike S wrote:
Hi all,
I noticed a very slight logic error in the solution to K&R Exercise 1-22
on the the CLC-Wiki, located at
http://www.clc-wiki.net/wiki/KR2_Exercise_1-22
Your fix looks correct to me at least. How about you edit the code on the
wiki and add your analysis to the discussion page?
I'm wondering now if it would be much benefit to change the Wiki -- I
found the other bug that you mentioned and am debating whether it's
worth posting my fix if it's still an incomplete solution. Or is it OK
to post incremental changes to the WIki?
I've spotted another bug that I won't point out in case readers would like
to find it for themselves.
The exercise reads as follows:
"Write a program to 'fold' long input lines into two or more shorter lines
after the last non-blank character that occurs before the n-th column of
input. Make sure your program does something intelligent with very long
lines, and if there are no blanks or tabs before the specified column."
Aside from that, I don't think that overwriting the n-th character with a
newline when a line contains no spaces before the n-th character conforms
to the spirit or the letter of the exercise.
Agreed. As I hinted above, I think I know what the other bug is, but
I'll keep the guessing game going for the other readers :-)
So, a small challenge for c.l.c readers: what's the smallest possible change
that could be made to this code that would preserve all input characters in
the output for over-length words without breaking the code's existing
conformance to the exercise's wording?
To fully complete the challenge, the adjustment should retain the fix
suggested by Mike S as well as fix the other unidentified bug.
Extra info: the existing code is already classified "category 1", meaning
that "it uses aspects of C which may not have been covered at the point in
the book at which the exercise appears", so use of pointer and dereference
operators is allowed.
[rest of post quoted unmodified aside from some whitespace reformatting of the
code]
And this is the solution provided on the clc-wiki, due to Rick Dearman
(note that I changed FOLDLENGTH to 25, in order to better show the
algorithm's effect):
/******************************************************
KnR 1-22
--------
Write a program that wraps very long lines of input
into two or more shorter lines.
Author: Rick Dearman
email: rick@xxxxxxxxxxxxxxxxxx
******************************************************/
#include <stdio.h>
#define MAXLINE 1000 /* max input line size */
char line[MAXLINE]; /*current input line*/
int getline(void); /* taken from the KnR book. */
int
main()
{
int t,len;
int location,spaceholder;
const int FOLDLENGTH=25; /* The max length of a line */
while (( len = getline()) > 0 )
{
if( len < FOLDLENGTH )
{
}
else
{
/* if this is an extra long line then we
** loop through it replacing a space nearest
** to the foldarea with a newline.
*/
t = 0;
location = 0;
while(t<len)
{
if(line[t] == ' ')
spaceholder = t;
if(location==FOLDLENGTH)
{
line[spaceholder] = '\n';
location = 0;
}
location++;
t++;
}
}
printf ( "%s", line);
}
return 0;
}
/* getline: specialized version */
int getline(void)
{
int c, i;
extern char line[];
for ( i=0;i<MAXLINE-1 && ( c=getchar()) != EOF && c != '\n'; ++i)
line[i] = c;
if(c == '\n')
{
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
Suppose this program is compiled and given the following text as input
(in the form of a single long line):
/ The computing world has undergone a revolution since the publication
of The C Programming Language in 1978. /
The program output given this input is shown below, using a FOLDLENGTH
of 25 and '*' column markers to visually indicate where the "fold"
margin is located:
************************* <-- characterss should not go past this column
The computing world has
undergone a revolution
since the publication of The
C Programming Language
in 1978.
Problem: The word "The" trails beyond the right margin that the program
is supposed to be enforcing. The offending code is in the body the
inner-most loop in main:
t = 0;
location = 0;
while(t<len)
{
if(line[t] == ' ')
spaceholder = t;
if(location==FOLDLENGTH)
{
line[spaceholder] = '\n';
location = 0;
}
location++;
t++;
}
Synopsis: if the program is in the middle of a word and
location==FOLDLENGTH becomes true, then 'spaceholder' contains the
location (in line) of the space character immediately preceding the
word. This space will be replaced by a newline, causing the program to
break the line before the word appears, which is correct behavior.
However, 'location' is set to zero relative to the current location in
the line, 't'. This location is not necessarily the location where the
newline was inserted. This causes the the value of 'location' to be off
by a few characters in situations where the newline is inserted in the
line before the current index 't'.
Remedy: 'location' should be reset relative to where the newline was
inserted, not relative to the current character being processed in line.
That is, the program should be looking for the condition
location==FOLDLENGTH relative to the beginning of the last line, not the
last character processed. Changing the line
location = 0;
to
location = t - spaceholder;
corrects this shortcoming.
--
http://members.dodo.com.au/~netocrat
.
- Follow-Ups:
- Re: Small Correction to K&R Exercise 1-22 Solution on CLC-Wiki
- From: Flash Gordon
- Re: Small Correction to K&R Exercise 1-22 Solution on CLC-Wiki
- References:
- Prev by Date: Re: speed of execution
- Next by Date: Re: speed of execution
- Previous by thread: Re: Small Correction to K&R Exercise 1-22 Solution on CLC-Wiki
- Next by thread: Re: Small Correction to K&R Exercise 1-22 Solution on CLC-Wiki
- Index(es):
Relevant Pages
|