By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,898 Members | 2,006 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,898 IT Pros & Developers. It's quick & easy.

K&R2 - section 1.5.3 , exercise 1-9

P: n/a
i have created solution which compiles and runs without any error/
warning but it does not work. i am not able to understand why. i
thought it is good to post my code here for correction before looking
at CLC-Wiki for K&R2 solutions:

--------------- PROGRAMME ------------
/* K&R2 section 1.5.3, exercise 1-9

STATEMENT:
write a programme to copy its input to output replacing
each string of 1 or more blanks with single blank.

*/

#include <stdio.h>

int main()
{
int c;
int scount = 0;

while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(scount != 0)
scount = scount + 1;
if(scount == 0)
putchar(c);
}

if(c != ' ')
{
putchar(c);
scount = 0;
}

}

return 0;
}
-------------- OUTPUT ----------------
[arch@voodo kr2]$ gcc -std=c99 -pedantic -Wall -Wextra ex_1-9.c
[arch@voodo kr2]$ ./a.out
like
like
and
and
and this
and this
and this
and this
[arch@voodo kr2]$

Mar 20 '07 #1
Share this Question
Share on Google+
16 Replies


P: n/a
On Mar 20, 4:39 pm, "arnuld" <geek.arn...@gmail.comwrote:
if(c == ' ')
{
if(scount != 0)
scount = scount + 1;
if(scount == 0)
putchar(c);
}
i GOT it, that code above is the culprit. i changed it to:

if(c == ' ')
{
if(scount == 0)
{
putchar(c);
scount = 1;
}
}
and it does what exactly i wanted :-)

thanks anyway

Mar 20 '07 #2

P: n/a
On 20 Mar, 11:39, "arnuld" <geek.arn...@gmail.comwrote:
i have created solution which compiles and runs without any error/
warning but it does not work. i am not able to understand why. i
thought it is good to post my code here for correction before looking
at CLC-Wiki for K&R2 solutions:

--------------- PROGRAMME ------------
/* K&R2 section 1.5.3, exercise 1-9

STATEMENT:
write a programme to copy its input to output replacing
each string of 1 or more blanks with single blank.

*/

#include <stdio.h>

int main()
{
int c;
int scount = 0;

while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(scount != 0)
scount = scount + 1;
if(scount == 0)
putchar(c);
}

if(c != ' ')
{
putchar(c);
scount = 0;
}

}

return 0;}

-------------- OUTPUT ----------------
[arch@voodo kr2]$ gcc -std=c99 -pedantic -Wall -Wextra ex_1-9.c
[arch@voodo kr2]$ ./a.out
like
like
and
and
and this
and this
and this
and this
[arch@voodo kr2]$
I know you've found your problem, but have you considered using a
Finite State Machine as an alternative solution? It's not really
needed here, but it might be a fun exercise.

Mar 20 '07 #3

P: n/a
On Mar 20, 5:16 pm, mark_blue...@pobox.com wrote:
I know you've found your problem, but have you considered using a
Finite State Machine as an alternative solution? It's not really
needed here, but it might be a fun exercise.
i did not know what are "Finite State Machines" (FSM) so i used
Wikipedia and found that variable "scount" is FSM in my programme.

but why it is bad here ?

BTW, i liked Chris Sidi's solution. it is much better and beautiful,as
my eyes see it:

http://clc-wiki.net/wiki/K%26R2_solu...r_1:Exercise_9
Mar 20 '07 #4

P: n/a
On 20 Mar, 12:47, "arnuld" <geek.arn...@gmail.comwrote:
On Mar 20, 5:16 pm, mark_blue...@pobox.com wrote:
I know you've found your problem, but have you considered using a
Finite State Machine as an alternative solution? It's not really
needed here, but it might be a fun exercise.

i did not know what are "Finite State Machines" (FSM) so i used
Wikipedia and found that variable "scount" is FSM in my programme.

but why it is bad here ?
Here's an FSM-style solution:-

#include <stdio.h>
int main(void) {
int c;
enum {
NORMAL,
SKIPPING_SPACES
} state = NORMAL;

while ((c = getc(stdin)) != EOF) {
switch(state) {
case(NORMAL):
putc(c,stdout);
if (c == ' ') {
state=SKIPPING_SPACES;
}
break;
case(SKIPPING_SPACES):
if (c != ' ') {
putc(c,stdout);
state=NORMAL;
}
break;
}
}
}

Mar 20 '07 #5

P: n/a
On 20 Mar 2007 04:39:31 -0700, "arnuld" <ge*********@gmail.comwrote:
>
--------------- PROGRAMME ------------
/* K&R2 section 1.5.3, exercise 1-9

STATEMENT:
write a programme to copy its input to output replacing
each string of 1 or more blanks with single blank.

*/
The basic idea of your solution is sound; though its implementation was
not.

Here's one of my own (old) solutions:

#include <stdio.h>

int main(void)
{
int c, space;

space = 0;
while ((c = getchar()) != EOF)
{
if (c == ' ')
{
if (space == 0)
{
space = 1;

putchar(' ');
}
}

if (c != ' ')
{
if (space == 1)
space = 0;

putchar(c);
}
}

return 0;
}

Another solution I came up with, happened to be (more or less) identical
with T&C's solution, IIRC:

#include <stdio.h>

int main(void)
{
int c, lastc;

lastc = 'x'; /*dummy*/
while ((c = getchar()) != EOF)
{
if (c != ' ')
putchar(c);

if (c == ' ')
if (lastc != ' ')
putchar(' ');

lastc = c;
}

return 0;
}
G. H.

--

E-mail: info<at>simple-line<Punkt>de
Mar 20 '07 #6

P: n/a
On Mar 20, 6:02 pm, mark_blue...@pobox.com wrote:
Here's an FSM-style solution:-

#include <stdio.h>
int main(void) {
int c;
enum {
NORMAL,
SKIPPING_SPACES
} state = NORMAL;
Erm... i have not encountered "enum" till yet. i am at chapter 1.

while ((c = getc(stdin)) != EOF) {
switch(state) {
case(NORMAL):
putc(c,stdout);
if (c == ' ') {
state=SKIPPING_SPACES;
}
break;
case(SKIPPING_SPACES):
if (c != ' ') {
putc(c,stdout);
state=NORMAL;
}
break;
}
}

}
it looks good and attractive, BTW

:-)

Mar 20 '07 #7

P: n/a
On Mar 20, 10:37 pm, Gregor H. <nomail@invalidwrote:

Here's one of my own (old) solutions:
ok, i will see :-)
if (c != ' ')
{
if (space == 1)
space = 0;

this is the only difference i have encountered. is it really
important ?
Another solution I came up with, happened to be (more or less) identical
with T&C's solution, IIRC:
i will feel happy, if you can tell me who is "T&C"

#include <stdio.h>

int main(void)
{
int c, lastc;

lastc = 'x'; /*dummy*/
i think "last = EOF" will be better. IIRC, i read that somewhere but
forgot where :-(
while ((c = getchar()) != EOF)
{
if (c != ' ')
putchar(c);

if (c == ' ')
if (lastc != ' ')
putchar(' ');

lastc = c;
}
looks better than my solution :-)

Mar 20 '07 #8

P: n/a
On 20 Mar 2007 11:29:35 -0700, "arnuld" <ge*********@gmail.comwrote:
>
this is the only difference i have encountered. is it really
important?
No. The if-construction is not needed.
>>
Another solution I came up with, happened to be (more or less) identical
with T&C's solution, IIRC:
i will feel happy, if you can tell me who is "T&C"
Ah, right. One name is Clovis L. Tondo; but the name of the other author is
Scott E. Gimpel. So I was talking about T&G.
>>
#include <stdio.h>

int main(void)
{
int c, lastc;

lastc = 'x'; /*dummy*/
i think "last = EOF" will be better.
Nonsense. EOF is not even a character!
>
looks better than my solution :-)
No. Both solutions are fine.
G. H.

--

E-mail: info<at>simple-line<Punkt>de
Mar 20 '07 #9

P: n/a
On 20 Mar 2007 11:23:18 -0700, "arnuld" <ge*********@gmail.comwrote:
>On Mar 20, 6:02 pm, mark_blue...@pobox.com wrote:
>Here's an FSM-style solution:-

#include <stdio.h>
int main(void) {
int c;
enum {
NORMAL,
SKIPPING_SPACES
} state = NORMAL;

Erm... i have not encountered "enum" till yet. i am at chapter 1.
Same with "switch ... case ...".
G. H.

--

E-mail: info<at>simple-line<Punkt>de
Mar 20 '07 #10

P: n/a
Gregor H. <nomail@invalidwrites:
On 20 Mar 2007 11:29:35 -0700, "arnuld" <ge*********@gmail.comwrote:
[...]
>>#include <stdio.h>

int main(void)
{
int c, lastc;

lastc = 'x'; /*dummy*/
i think "last = EOF" will be better.
Nonsense. EOF is not even a character!
Right, neither is lastc.

EOF is a value of type int, guaranteed to be unequal to any valid
character value that can be returned by getchar(), which I think
is exactly what you want here.

You use 'x' as a dummy value, unequal to any of the characters you're
looking for -- which breaks if you change the program to search for
'x' characters. Using EOF is a bit more robust.

You could also add a flag that indicates whether the value of lastc is
meaningful.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 20 '07 #11

P: n/a
On Mar 21, 2:25 am, Keith Thompson <k...@mib.orgwrote:

Nonsense. EOF is not even a character!

Right, neither is lastc.
yep, that is why said "EOF"
EOF is a value of type int, guaranteed to be unequal to any valid
character value that can be returned by getchar(), which I think
is exactly what you want here.
:-)

You use 'x' as a dummy value, unequal to any of the characters you're
looking for -- which breaks if you change the program to search for
'x' characters. Using EOF is a bit more robust.

that was my logic of suggesting EOF, to be exact.
You could also add a flag that indicates whether the value of lastc is
meaningful.
may you show this with some code ?

actually i did not get it.

Mar 21 '07 #12

P: n/a
"arnuld" <ge*********@gmail.comwrites:
>On Mar 21, 2:25 am, Keith Thompson <k...@mib.orgwrote:
[...]
>You use 'x' as a dummy value, unequal to any of the characters you're
looking for -- which breaks if you change the program to search for
'x' characters. Using EOF is a bit more robust.

that was my logic of suggesting EOF, to be exact.
>You could also add a flag that indicates whether the value of lastc is
meaningful.

may you show this with some code ?

actually i did not get it.
The program sets lastc to 'x' (or EOF, or whatever) to indicate that
it doesn't have a valid value (because there isn't a previous
character yet). Another approach would be a separate flag variable,
such as:

int lastc_is_valid = 0;

When you assign a value to lastc, set lastc_is_valid to 1; don't look
at the value of lastc unless lastc_is_valid has been set to 1.

A separate variable isn't necessary here, but there are other cases
where it could be; for example, if all possible values of lastc could
represent valid data, there wouldn't be room for the flag information.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 21 '07 #13

P: n/a
On Mar 21, 1:43 pm, Keith Thompson <k...@mib.orgwrote:

The program sets lastc to 'x' (or EOF, or whatever) to indicate that
it doesn't have a valid value (because there isn't a previous
character yet). Another approach would be a separate flag variable,
such as:

int lastc_is_valid = 0;

When you assign a value to lastc, set lastc_is_valid to 1; don't look
at the value of lastc unless lastc_is_valid has been set to 1.
ok, you meant "Finistate State Machine"

Mar 21 '07 #14

P: n/a
ok, you meant "Finistate State Machine"

i meant "Finite State Machine"

sorry
Mar 21 '07 #15

P: n/a
On 20 Mar 2007 21:52:07 -0700, "arnuld" <ge*********@gmail.comwrote:
>>>
Nonsense. EOF is not even a character!
Right, neither is lastc.
yep, that is why [i] said "EOF"
I see. But the name of "lastc" seems to refer to a char (imho). Actually,
the definition of this variable could also have been

char lastc;

--- in which case "lastc = EOF" would be a bug.

Since...
>>
EOF is a value of type int, guaranteed to be unequal to any valid
character value that can be returned by getchar() ...
Right.
>>
You use 'x' as a dummy value, unequal to any of the characters
you're looking for
No. *I* am (or was) ONLY looking for the character ' '.

But it's true, this would break...
>>
if you change the program to search for 'x' characters.
(But see comment below.)
>>
Using EOF is a bit more robust.
Sounds reasonable. You (he) might have a point here.
>
that was my logic of suggesting EOF, to be exact.
Well, great! :-)

On the other hand, I personally seem to sympathize with the following point
of view:

"Trying to anticipate every possible future contingency can drive you
crazy, and you'll generally guess wrong anyway. In this modern day of
screen editors and fast compilers, I don't hesitate to change a module when
I feel I need a more powerful one. Until then, I'll write only what I
need." (Jack W. Crenshaw, Let's Built a Compiler!)
G. H.

--

E-mail: info<at>simple-line<Punkt>de
Mar 21 '07 #16

P: n/a
Groovy hepcat arnuld was jivin' on 20 Mar 2007 11:23:18 -0700 in
comp.lang.c.
Re: K&R2 - section 1.5.3 , exercise 1-9's a cool scene! Dig it!
>On Mar 20, 6:02 pm, mark_blue...@pobox.com wrote:
>Here's an FSM-style solution:-

#include <stdio.h>
int main(void) {
int c;
enum {
NORMAL,
SKIPPING_SPACES
} state = NORMAL;

Erm... i have not encountered "enum" till yet. i am at chapter 1.
It doesn't matter. You can use an int instead. Basically he's not
doing anything you didn't do in your (fixed) version, except using
some of C's "syntactic sugar". Your version used a finite state
machine, same as his. Although your state variable, scount, was rather
oddly named. It looks like you originally intended to count the number
of spaces. Of course, you found out that you don't have to do that,
just keep track of whether you're writing characters or not.
> while ((c = getc(stdin)) != EOF) {
switch(state) {
case(NORMAL):
putc(c,stdout);
if (c == ' ') {
state=SKIPPING_SPACES;
}
break;
case(SKIPPING_SPACES):
if (c != ' ') {
putc(c,stdout);
state=NORMAL;
}
break;
}
}

}
Mark's version looks almost identical to my own, except I used a
simple if...else construct instead of a switch. Either way is fine,
though.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Mar 24 '07 #17

This discussion thread is closed

Replies have been disabled for this discussion.