K&R2, Exercise 1-12

J

Josh Zenker

I've written a solution based on Richard Heathfield's
(http://users.powernet.co.uk/eton/kandr2/krx112.html), but I'm
encountering some unexpected program behavior. Here's my code:

#include <stdio.h>

#define IN 1 /* inside a space */
#define OUT 0 /* outside a space */

/* prints input one word per line */
int main() {
int c, state;

state = OUT;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
if (state == OUT) {
state = IN;
putchar('\n');
}
/* else print nothing */
} else {
state = OUT;
putchar(c);
}
}

return 0;
}

I compiled with gcc-3.4.6 on Gentoo. When I run the executable, it
works fine for inputs like "foo bar" but gets fouled up when the input
contains a newline. For example, I typed "foo" followed by Ctrl+V and
Enter, followed by "bar" (i.e. "foo^Mbar") and got only "bar" as the
output. What's going on here?

JZ
 
M

Michael Mair

Josh said:
I've written a solution based on Richard Heathfield's
(http://users.powernet.co.uk/eton/kandr2/krx112.html), but I'm
encountering some unexpected program behavior. Here's my code:

#include <stdio.h>

#define IN 1 /* inside a space */
#define OUT 0 /* outside a space */

If you just want different values, enumeration constants IMO are
a better choice.
/* prints input one word per line */
int main()

int main (void)
is the recommended form around here.
{
int c, state;

state = OUT;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
if (state == OUT) {
state = IN;
putchar('\n');
}
/* else print nothing */
} else {
state = OUT;
putchar(c);
}
}

return 0;
}

I compiled with gcc-3.4.6 on Gentoo. When I run the executable, it
works fine for inputs like "foo bar" but gets fouled up when the input
contains a newline. For example, I typed "foo" followed by Ctrl+V and
Enter, followed by "bar" (i.e. "foo^Mbar") and got only "bar" as the
output. What's going on here?

Are you sure that this input gives you what you expect?
Change your output to
printf("\\n[%d]\n", '\n');
and
printf("%c[%d]\n", c, c);
respectively to see what is going on.

If you can, redirect the input from a file to test your
programme -- then it should work as expected.

Cheers
Michael
 
O

Old Wolf

Josh said:
I've written a solution based on Richard Heathfield's
(http://users.powernet.co.uk/eton/kandr2/krx112.html), but I'm
encountering some unexpected program behavior. Here's my code:

#include <stdio.h>

#define IN 1 /* inside a space */
#define OUT 0 /* outside a space */

/* prints input one word per line */
int main() {
int c, state;

state = OUT;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
if (state == OUT) {
state = IN;
putchar('\n');
}
/* else print nothing */
} else {
state = OUT;
putchar(c);
}
}

return 0;
}

I compiled with gcc-3.4.6 on Gentoo. When I run the executable, it
works fine for inputs like "foo bar" but gets fouled up when the input
contains a newline. For example, I typed "foo" followed by Ctrl+V and
Enter, followed by "bar" (i.e. "foo^Mbar") and got only "bar" as the
output. What's going on here?

In ASCII, ^M is a carriage return. ^J is newline.

Probably your terminal treats it as such, i.e. it returns the cursor
to the start of the line but does not go down a line.

So your program outputs foo, and then goes back to the start of
the same line, and overwrites foo with bar.

Try typing "foot^Mbar", you will probably see "bart".
 
S

Spiros Bousbouras

Old said:
In ASCII, ^M is a carriage return. ^J is newline.

Probably your terminal treats it as such, i.e. it returns the cursor
to the start of the line but does not go down a line.

So your program outputs foo, and then goes back to the start of
the same line, and overwrites foo with bar.

Try typing "foot^Mbar", you will probably see "bart".

Yes , this must be it. To be absolutely certain you
can pipe the output of the programme to od.

A more advanced version of your programme may
contain some special logic to handle control characters.
 
J

Josh Zenker

Old said:
In ASCII, ^M is a carriage return. ^J is newline.

Probably your terminal treats it as such, i.e. it returns the cursor
to the start of the line but does not go down a line.

So your program outputs foo, and then goes back to the start of
the same line, and overwrites foo with bar.

Try typing "foot^Mbar", you will probably see "bart".

Yes, you're absolutely right. Thanks for clearing that up.

JZ
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top