M
Mike S
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
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."
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: (e-mail address removed)
******************************************************/
#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 = c;
if(c == '\n')
{
line = c;
++i;
}
line = '\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.
Mike S
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
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."
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: (e-mail address removed)
******************************************************/
#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 = c;
if(c == '\n')
{
line = c;
++i;
}
line = '\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.
Mike S