K&R2 - section 1.5.3 , exercise 1-9


A

arnuld

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 ----------------
[[email protected] kr2]$ gcc -std=c99 -pedantic -Wall -Wextra ex_1-9.c
[[email protected] kr2]$ ./a.out
like
like
and
and
and this
and this
and this
and this
[[email protected] kr2]$
 
Ad

Advertisements

A

arnuld

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
 
M

mark_bluemel

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 ----------------
[[email protected] kr2]$ gcc -std=c99 -pedantic -Wall -Wextra ex_1-9.c
[[email protected] kr2]$ ./a.out
like
like
and
and
and this
and this
and this
and this
[[email protected] 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.
 
A

arnuld

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&R2_solutions:Chapter_1:Exercise_9
 
M

mark_bluemel

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;
}
}
}
 
G

Gregor H.

--------------- 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.
 
Ad

Advertisements

A

arnuld

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

:)
 
A

arnuld

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 :)
 
G

Gregor H.

this is the only difference i have encountered. is it really
important?
No. The if-construction is not needed.
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.
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.
 
K

Keith Thompson

Gregor H. said:
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.
 
Ad

Advertisements

A

arnuld

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.
 
K

Keith Thompson

arnuld said:
that was my logic of suggesting EOF, to be exact.


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.
 
A

arnuld

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"
 
G

Gregor H.

Right, neither is lastc.
yep, that is why 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...
No. *I* am (or was) ONLY looking for the character ' '.

But it's true, this would break...(But see comment below.)
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.
 
Ad

Advertisements

P

Peter Shaggy Haywood

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!
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.

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"?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top