Velocity Reviews > C Programming: A Modern Approach - Chapter 15 Exercise 5

# C Programming: A Modern Approach - Chapter 15 Exercise 5

Simon Morgan
Guest
Posts: n/a

 07-22-2005
Hi,

Does anybody have a solution or a hint for Exercise 5 of Chapter 15 of
K.N. King's book C Programming: A Modern Approach? I spent all of
yesterday evening staring at it and drooling. The author sure does have a
knack for making me feel like a dumbass, or maybe it's just that I am.

The following code pads out sentences with extra spaces between words so
that each line takes up the same amount of space on screen. As is, the
code will favour the end of the line when distributing the extra spaces.
The task is to modify it so that it alternates between distribution of the
extra spaces favouring the end of the line and the beginning of the line.

void write_line(void)
{
int extra_spaces, spaces_to_insert, i, j;

extra_spaces = MAX_LINE_LEN - line_len;
for (i = 0; i < line_len; i++) {
if (line[i] != ' ')
putchar(line[i]);
else {
spaces_to_insert = extra_spaces / (num_words - 1);
for (j = 1; j <= spaces_to_insert + 1; j++)
putchar(' ');
extra_spaces -= spaces_to_insert;
num_words--;
}
}
putchar('\n');
}

I cannot for the life of me figure out a solution beyond parsing the
sentence first and adding the number of spaces to an array to be used when
printing the sentence to screen, but this feels like an awful kludge. The
closest I've come to a decent solution is to add extra_spaces % (num_words
- 1) to spaces_to_insert but this results in the extra spaces not being
distributed evenly.

Thanks.

Steffen Buehler
Guest
Posts: n/a

 07-22-2005
Simon Morgan wrote:

> The following code pads out sentences with extra spaces between words
> so that each line takes up the same amount of space on screen. As is,
> the code will favour the end of the line when distributing the extra
> spaces. The task is to modify it so that it alternates between
> distribution of the extra spaces favouring the end of the line and
> the beginning of the line.
>
> void write_line(void)
> {
> int extra_spaces, spaces_to_insert, i, j;
>
> extra_spaces = MAX_LINE_LEN - line_len;
> for (i = 0; i < line_len; i++) {
> if (line[i] != ' ')
> putchar(line[i]);
> else {
> spaces_to_insert = extra_spaces / (num_words - 1);

This is the troublemaker. Let's say you have 8 extra spaces and 4 words.
Then spaces_to_insert will be 8/3 = 2.666 and be _cut_ _off_ to 2. So
"too few" spaces will be inserted first.

If you want to have "too much" spaces first, change this line to

spaces_to_insert = int(0.5 + extra_spaces / (num_words - 1.0);

(Beware to make the division floating-point by using 1.0 instead of 1 or
casting extra_spaces to float, otherwise the rounding will not work.)

> for (j = 1; j <= spaces_to_insert + 1; j++)
> putchar(' ');
> extra_spaces -= spaces_to_insert;
> num_words--;
> }
> }
> putchar('\n');
> }

Regards
Steffen

Simon Morgan
Guest
Posts: n/a

 07-22-2005
On Fri, 22 Jul 2005 12:54:23 +0200, Steffen Buehler wrote:

> spaces_to_insert = int(0.5 + extra_spaces / (num_words - 1.0);
>
> (Beware to make the division floating-point by using 1.0 instead of 1 or
> casting extra_spaces to float, otherwise the rounding will not work.)

Thanks for the quick reply Steffen.

Just one question. Is int a function or am I supposed to cast the result
of the expression to an int? If I cast it the output isn't how I would
expect it to be or how I think the book expects it to be (the spaces seem
to be randomly distributed throughout the line) so I assume it's a
function but I can't seem to find any mention of it in the book or in the
man pages installed on my system.

Suman
Guest
Posts: n/a

 07-22-2005

Simon Morgan wrote:
> On Fri, 22 Jul 2005 12:54:23 +0200, Steffen Buehler wrote:
>
> > spaces_to_insert = int(0.5 + extra_spaces / (num_words - 1.0);
> >
> > (Beware to make the division floating-point by using 1.0 instead of 1 or
> > casting extra_spaces to float, otherwise the rounding will not work.)

>
> Thanks for the quick reply Steffen.
>
> Just one question. Is int a function or am I supposed to cast the result
> of the expression to an int?

May I suggest you get a book? Or, the standard. Or, atleast the draft.
`int' is one of the standard signed integer types(6.2.5.)
And a keyword (6.4.1.)

>If I cast it the output isn't how I would
> expect it to be or how I think the book expects it to be (the spaces seem
> to be randomly distributed throughout the line) so I assume it's a
> function but I can't seem to find any mention of it in the book or in the
> man pages installed on my system.

Steffen Buehler
Guest
Posts: n/a

 07-22-2005
Simon Morgan wrote:

> On Fri, 22 Jul 2005 12:54:23 +0200, Steffen Buehler wrote:
>
>> spaces_to_insert = int(0.5 + extra_spaces / (num_words - 1.0);

>
> Is int a function or am I supposed to cast the
> result of the expression to an int?

It's a simple cast, sorry for the confusion. The line should read

spaces_to_insert = (int)(0.5 + extra_spaces / (num_words - 1.0));

(I forgot the last closing bracket as well...)

> If I cast it the output isn't how
> I would expect it to be or how I think the book expects it to be (the
> spaces seem to be randomly distributed throughout the line)

Strange. It works fine here. What did you do with the missing bracket?
What are your values for extra_spaces and num_words?

Regards
Steffen

Simon Morgan
Guest
Posts: n/a

 07-22-2005
On Fri, 22 Jul 2005 13:41:30 +0200, Steffen Buehler wrote:

> It's a simple cast, sorry for the confusion. The line should read
>
> spaces_to_insert = (int)(0.5 + extra_spaces / (num_words - 1.0));
>
> (I forgot the last closing bracket as well...)
>
> Strange. It works fine here. What did you do with the missing bracket?

Mine looks the same as your corrected version.

> What are your values for extra_spaces and num_words?

extra_spaces = 9
num_words = 9
C is quirky, flawed, and an enormous success. While
extra_spaces = 0
num_words = 9
accidents of history surely helped, it evidently satisfied a
extra_spaces = 2
num_words = 8
need for a system implementation language efficient enough
extra_spaces = 0
num_words = 8
to displace assembly language, yet sufficiently abstract and
extra_spaces = 4
num_words = 9
fluent to describe algorithms and interactions in a wide
variety of environments. -- Dennis M. Ritchie

Simon Morgan
Guest
Posts: n/a

 07-22-2005
On Fri, 22 Jul 2005 11:47:53 +0000, Simon Morgan wrote:

> extra_spaces = 9
> num_words = 9
> C is quirky, flawed, and an enormous success. While
> extra_spaces = 0
> num_words = 9

Apologies for the crappy formatting. I don't know whether It's my news
server or client but it certainly didn't look like that before I posted
it.

extra_spaces = 9
num_words = 9
C is quirky, flawed, and an enormous success. While
extra_spaces = 0
num_words = 9
accidents of history surely helped, it evidently satisfied a
extra_spaces = 2
num_words = 8
need for a system implementation language efficient enough
extra_spaces = 0
num_words = 8
to displace assembly language, yet sufficiently abstract and
extra_spaces = 4
num_words = 9
fluent to describe algorithms and interactions in a wide
variety of environments. -- Dennis M. Ritchie

Simon Morgan
Guest
Posts: n/a

 07-22-2005
On Fri, 22 Jul 2005 11:52:59 +0000, Simon Morgan wrote:

> C is quirky, flawed, and an enormous success. While extra_spaces
> = 0

*sigh*

Steffen Buehler
Guest
Posts: n/a

 07-22-2005
Simon Morgan wrote:

> extra_spaces = 9
> num_words = 9
> C is quirky, flawed, and an enormous success. While

Let's stick to this. Here's what I get:

| C is quirky, flawed, and an enormous success. While

How come you insert most spaces at the last position but one? Your
remaining code must somewhere differ from the one you posted here.

Regards
Steffen

Simon Morgan
Guest
Posts: n/a

 07-22-2005
On Fri, 22 Jul 2005 14:10:47 +0200, Steffen Buehler wrote:

> How come you insert most spaces at the last position but one? Your
> remaining code must somewhere differ from the one you posted here.

Do you have code for alternating between endianness? I haven't bothered
with that because it should be trivial to add. Right now all I'm trying to
do is get space distribution to favour the beginning of the line (the
non-floating point algorithm but in reverse if you see what I mean).

Here is my current code:

void write_line(void)
{
int extra_spaces, spaces_to_insert, i, j;

extra_spaces = MAX_LINE_LEN - line_len;
printf("extra_spaces = %d\n", extra_spaces);
printf("num_words = %d\n", num_words);
for (i = 0; i < line_len; i++) {
if (line[i] != ' ')
putchar(line[i]);
else {
spaces_to_insert = (int)(0.5 + extra_spaces / (num_words - 1.0));
for (j = 1; j <= spaces_to_insert + 1; j++)
putchar(' ');
extra_spaces -= spaces_to_insert;
num_words--;
}
}
putchar('\n');
}