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

Exercise 1-10 in K&R2

P: n/a
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
; /* null statement */
putchar(c);
}
}

return 0;
}

It produces the expected output when compiled with gcc-3.4.6 on a
Gentoo box. So I'm assuming the code is at least correct, though not
necessarily optimal.

JZ

Sep 21 '06 #1
Share this Question
Share on Google+
16 Replies


P: n/a
Josh Zenker wrote:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
; /* null statement */
putchar(c);
Doesn't this print an extra space? You printed the character before the if.

--
Ian Collins.
Sep 21 '06 #2

P: n/a
Ian Collins wrote:
Josh Zenker wrote:
This is my attempt at exercise 1-10 in K&R2.
Oops, I meant exercise 1-9. I also realized after I posted this that
there's probably a ton of code out there for this exact exercise. I'll
search the group archives.
The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
; /* null statement */
putchar(c);

Doesn't this print an extra space? You printed the character before the if.
I tested it on several different inputs, and it seems to produce the
desired output. For example, input "argle bargle" produces output
"argle bargle".

JZ

Sep 21 '06 #3

P: n/a
Josh Zenker wrote:
Ian Collins wrote:
>>Josh Zenker wrote:
>>>This is my attempt at exercise 1-10 in K&R2.


Oops, I meant exercise 1-9. I also realized after I posted this that
there's probably a ton of code out there for this exact exercise. I'll
search the group archives.

>>>The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
; /* null statement */
putchar(c);

Doesn't this print an extra space? You printed the character before the if.


I tested it on several different inputs, and it seems to produce the
desired output. For example, input "argle bargle" produces output
"argle bargle".
Silly me, I didn't spot the while terminating with c != ' '.

--
Ian Collins.
Sep 21 '06 #4

P: n/a
Josh Zenker wrote:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
You need to check for EOF here.
; /* null statement */
putchar(c);
}
}

return 0;
}

It produces the expected output when compiled with gcc-3.4.6 on a
Gentoo box. So I'm assuming the code is at least correct, though not
necessarily optimal.
If you make the above correction then it's fine.

Sep 21 '06 #5

P: n/a
Josh Zenker wrote:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
Josh Zenker wrote:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
You have missed the EOF check here (as somebody has pointed out
already).
That is why it is a good idea to have one point input for any text
processing. Consider the following.

#include <stdio.h>

int main(void)
{
int c;
int blank = 0;
while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(!blank)
{
blank = 1;
putchar(c);
}
}
else
{
blank = 0;
putchar(c);
}
}
return 0;
}

Sep 21 '06 #6

P: n/a
Josh Zenker wrote:
>
This is my attempt at exercise 1-10 in K&R2. The code looks
sloppy to me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
; /* null statement */
putchar(c);
}
}

return 0;
}

It produces the expected output when compiled with gcc-3.4.6 on a
Gentoo box. So I'm assuming the code is at least correct, though
not necessarily optimal.
I like:

#include stdio.h

int main(void) {
int ch, lastch = EOF;

while (EOF != (ch = getchar())) {
if ((' ' != ch) && (' ' != lastch)) putchar(ch);
lastch = ch;
}
return 0;
} /* untested */

--
"The most amazing achievement of the computer software industry
is its continuing cancellation of the steady and staggering
gains made by the computer hardware industry..." - Petroski
--
Posted via a free Usenet account from http://www.teranews.com

Sep 21 '06 #7

P: n/a

Josh Zenker wrote:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to
me. Is there a more elegant way to do this?
You can do this two general ways

(1) Note the state of "multiple spaces" by using a variable.

(2) Note it by your place in the code.

The main drawback to (2) is duplicated loops, which increases the
likelyhood you forget to do every check that is needed in every loop.
Hey! That happened, you're not checking for EOF while getting blanks!
You'll end up printing EOF as a character!

So I'd recommend method (1). Then you'll have just one place to do a
getchar, check for EOF, do a putchar. Hey! there's a problem there
too! You're not checking for error on putchar(). Don't feel bad, not
checking for errors has become rife. See any Microsoft example code.

Sep 21 '06 #8

P: n/a
On Thu, 21 Sep 2006, CBFalconer wrote:

[snip]
I like:

#include stdio.h

int main(void) {
int ch, lastch = EOF;

while (EOF != (ch = getchar())) {
if ((' ' != ch) && (' ' != lastch)) putchar(ch);
lastch = ch;
}
return 0;
} /* untested */
I assume that your '<' and '>' keys are broken today. :-)

Tak-Shing
Sep 21 '06 #9

P: n/a
Tak-Shing Chan wrote:
On Thu, 21 Sep 2006, CBFalconer wrote:

[snip]
>I like:

#include stdio.h

int main(void) {
int ch, lastch = EOF;

while (EOF != (ch = getchar())) {
if ((' ' != ch) && (' ' != lastch)) putchar(ch);
lastch = ch;
}
return 0;
} /* untested */

I assume that your '<' and '>' keys are broken today. :-)
Huh? I don't understand.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

--
Posted via a free Usenet account from http://www.teranews.com

Sep 21 '06 #10

P: n/a
CBFalconer said:
Tak-Shing Chan wrote:
>On Thu, 21 Sep 2006, CBFalconer wrote:

[snip]
>>I like:

#include stdio.h
<SNIP>
>>
I assume that your '<' and '>' keys are broken today. :-)

Huh? I don't understand.
How about now? :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Sep 21 '06 #11

P: n/a
CBFalconer wrote:
Josh Zenker wrote:
>This is my attempt at exercise 1-10 in K&R2. The code looks
sloppy to me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
; /* null statement */
putchar(c);
}
}

return 0;
}

It produces the expected output when compiled with gcc-3.4.6 on a
Gentoo box. So I'm assuming the code is at least correct, though
not necessarily optimal.

I like:

#include stdio.h

int main(void) {
int ch, lastch = EOF;

while (EOF != (ch = getchar())) {
if ((' ' != ch) && (' ' != lastch)) putchar(ch);
lastch = ch;
}
return 0;
} /* untested */
Testing is good. How about..

#include <stdio.h>

int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (!(last == ' ' && ch == ' '))
putchar(ch);
last = ch;
}
return 0;
}
...or..

#include <stdio.h>

int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (last != ' ' || ch != ' ')
putchar(ch);
last = ch;
}
return 0;
}
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Sep 21 '06 #12

P: n/a
Josh Zenker wrote:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to
me. Is there a more elegant way to do this?

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
; /* null statement */
putchar(c);
}
}

return 0;
}

It produces the expected output when compiled with gcc-3.4.6 on a
Gentoo box. So I'm assuming the code is at least correct, though not
necessarily optimal.

JZ
Hi Josh. That's Exercise 1-9 in my book, on page 20.

#include <stdio.h>

int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (last != ' ' || ch != ' ')
putchar(ch);
last = ch;
}
return 0;
}

Elegance?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Sep 21 '06 #13

P: n/a
Richard Heathfield wrote:
CBFalconer said:
>Tak-Shing Chan wrote:
>>On Thu, 21 Sep 2006, CBFalconer wrote:

[snip]

I like:

#include stdio.h
<SNIP>
>>>
I assume that your '<' and '>' keys are broken today. :-)

Huh? I don't understand.

How about now? :-)
AHA ! :-) Good thing I put in the 'untested' comment.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
--
Posted via a free Usenet account from http://www.teranews.com

Sep 22 '06 #14

P: n/a
So far we've had 3 versions of code performing the
task which is exercise 1-10 in K&R2:

VERSION 1

#include <stdio.h>

/* copies input to output, printing */
/* series of blanks as a single one */
int main() {
int c;

while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ')
if (c == EOF) return 0 ;
putchar(c);
}
}
return 0;
}

VERSION 2

#include <stdio.h>

int main(void)
{
int c;
int blank = 0;
while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(!blank)
{
blank = 1;
putchar(c);
}
}
else
{
blank = 0;
putchar(c);
}
}
return 0;
}

VERSION 3

#include <stdio.h>

int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (last != ' ' || ch != ' ')
putchar(ch);
last = ch;
}
return 0;
}

Judging from some of the statements made here some
people consider versions 2 and 3 preferable on the
basis that they are less prone to bugs than version
1 which did have a bug in its original inception.

Personally I prefer version 1 because versions 2 and
3 have an extra assignment at every iteration of the
loop. On some platforms this *will* make a difference
in performance. Even if it won't or the difference in
performance turns out to be miniscule (and that will almost
certainly turn out to be the case on every realistic
input) it still does not agree at all with my sense of
aesthetics to introduce extra instructions in such a
blatant manner.

Apart from that I actually consider version 3 the
harder to write and verify.

Sep 22 '06 #15

P: n/a
"Spiros Bousbouras" <sp****@gmail.comwrites:
So far we've had 3 versions of code performing the
task which is exercise 1-10 in K&R2:
VERSION 1
int main() {
int c;
while ((c = getchar()) != EOF) {
putchar(c);
if (c == ' ') {
while ((c = getchar()) == ' ') if (c == EOF) return 0;
putchar(c);
}
}
return 0;
}
VERSION 2
int main(void) {
int c, blank = 0;
while((c = getchar()) != EOF) {
if(c == ' ') {
if(!blank) {
blank = 1;
putchar(c);
}
} else {
blank = 0;
putchar(c);
}
}
return 0;
}
VERSION 3
int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (last != ' ' || ch != ' ')
putchar(ch);
last = ch;
}
return 0;
}
[cut]
Personally I prefer version 1 because versions 2 and
3 have an extra assignment at every iteration of the
loop. On some platforms this *will* make a difference
in performance.
There are only two integers which both will probably be stored in
registers so a single "mov reg, reg" instruction won't make a big
difference IMO.
Even if it won't or the difference in
performance turns out to be miniscule (and that will almost
certainly turn out to be the case on every realistic
input) it still does not agree at all with my sense of
aesthetics to introduce extra instructions in such a
blatant manner.

Apart from that I actually consider version 3 the
harder to write and verify.
IMO the 3rd version is the easiest to write and understand. It's
straightforward, ie. the exercise is about printing all characters
unless it is a space and the previous character was a space, so if the
previous character (last != ' ') was not a space or this character is
not a space (ch != ' ') we shall print the character.

Moreover, there is only one way the loop may stop (ie. the loop
condition) and the first version involves return statement to stop the
loop which some prefer to avoid (just like break statement).

Only I would do:

#v+
#include <stdio.h>
int main(void) {
int ch, last = 0;
while ((ch = getchar()) != EOF) {
if (last != ' ' || ch != ' ') {
putchar(last = ch);
}
}
return 0;
}
#v-
--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--
Sep 22 '06 #16

P: n/a
On Thu, 21 Sep 2006 20:48:18 -0400, CBFalconer <cb********@yahoo.com>
wrote:
>Richard Heathfield wrote:
>CBFalconer said:
>>Tak-Shing Chan wrote:
On Thu, 21 Sep 2006, CBFalconer wrote:

[snip]

I like:
>
#include stdio.h
>
<SNIP>
>>>>
I assume that your '<' and '>' keys are broken today. :-)

Huh? I don't understand.

How about now? :-)

AHA ! :-) Good thing I put in the 'untested' comment.
Perhaps in the future you should change "untested" to "uncompiled" or
"uncompiled and untested" in your comments. Not compiling
code--without errors--is akin to and arguably worse than top-posting.

--
jay
Sep 23 '06 #17

This discussion thread is closed

Replies have been disabled for this discussion.