K&R2 exercise question

C

Chris Readle

Ok, I've just recently finished a beginning C class and now I'm working
through K&R2 (alongside the C99 standard) to *really* learn C.

So anyway, I'm working on an exercise in chapter one which give me
strange behavior. Here is the code I've written:
/******************************************************************************
* K&R2 Exercise 1-9
* Write a program to copy its input to its output, replacing strings
of blanks
* with a single blank.
******************************************************************************/
#include <stdio.h>

int main(void) {

int c= 0, lastc= 0;

while((c= getchar()) != EOF) {

if (c == ' ') {
if (lastc != ' ') {//if c *is* a space and lastc is
putchar(c);//*not* a space, print the char
lastc= c;
}//end inner if
}//end outer if

if (c != ' ') {//if c isn't a space don't worry about it
putchar(c);
lastc =c;
}//end if
}//end while

return 0;
}


The problem I'm having is that when I run the program, I get no
execution, just returned to a prompt. However, when I run gdb on it
(even if I just "run" the program within gdb) it works, and even does
what I expected it to. Can anyone explain this one to me?

crr
 
J

Jack Klein

Ok, I've just recently finished a beginning C class and now I'm working
through K&R2 (alongside the C99 standard) to *really* learn C.

So anyway, I'm working on an exercise in chapter one which give me
strange behavior. Here is the code I've written:
/******************************************************************************
* K&R2 Exercise 1-9
* Write a program to copy its input to its output, replacing strings
of blanks
* with a single blank.
******************************************************************************/
#include <stdio.h>

int main(void) {

int c= 0, lastc= 0;

while((c= getchar()) != EOF) {

if (c == ' ') {
if (lastc != ' ') {//if c *is* a space and lastc is
putchar(c);//*not* a space, print the char
lastc= c;
}//end inner if
}//end outer if

if (c != ' ') {//if c isn't a space don't worry about it

I hope you know that the line above could be replaced with:
else {
putchar(c);
lastc =c;
}//end if
}//end while

return 0;
}


The problem I'm having is that when I run the program, I get no
execution, just returned to a prompt. However, when I run gdb on it
(even if I just "run" the program within gdb) it works, and even does
what I expected it to. Can anyone explain this one to me?

crr

Does your input contain a newline? In C it is implementation defined
whether the final line of output to a text stream requires a final
'\n' or not. Some implementations will not output the final line of
text to the display device if it does not end in a newline.

Try adding:

putchar('\n');

....just above the return from main().
 
C

Chris Readle

Jack said:
I hope you know that the line above could be replaced with:
else {
Yes, I knew that, but I'm trying to follow the book closely and since it
hasn't covered else yet...
Does your input contain a newline? In C it is implementation defined
whether the final line of output to a text stream requires a final
'\n' or not. Some implementations will not output the final line of
text to the display device if it does not end in a newline.

Try adding:

putchar('\n');

...just above the return from main().
Well, the input *would* contain a newline, but when it has the problem
previously described, I don't get to input anything. Basically, I call
the program, press enter and am immediately returned to the prompt.

I have done some further research on this, and I have discovered that if
I start a new instance of the shell, it runs just dandy the first time,
but subsequent runs return to the prompt without allowing any input.

I tried adding the newline just before the return statement in main(),
but all that does is put an additional newline on the screen when I call
the program.

crr
 
O

Ori Bernstein

Can anyone explain this one to me?

At a guess- the exec is called test. You're running it by typing 'test' in
the command line.

Try 'which test' - somehow I don't think you're running the program you
think you're running.
 
C

Chris Readle

Ori said:
At a guess- the exec is called test. You're running it by typing 'test' in
the command line.

Try 'which test' - somehow I don't think you're running the program you
think you're running.
Actually, the executable is exer1-10.exe. And, while I have both
GNU/Linux(Fedora I think right now, though it might be Debian or
Mandrake....I forget) FreeBSD (which I mostly use as my main partition)
partitions on my system, I'm doing this coding on my Windows partition,
so which wouldn't get me very far. ;)

Thanks for the suggestion, though.

crr
 
M

Martin Ambuhl

Chris said:
Ok, I've just recently finished a beginning C class and now I'm working
through K&R2 (alongside the C99 standard) to *really* learn C.

So anyway, I'm working on an exercise in chapter one which give me
strange behavior. Here is the code I've written:
[...]
The problem I'm having is that when I run the program, I get no
execution, just returned to a prompt.
> ... Can anyone explain this one to me?

Your code executes properly. If you are having a problem, it is
probably with your method of using your compiler.
 
A

Anjali M

Chris Readle said:
Ok, I've just recently finished a beginning C class and now I'm working
through K&R2 (alongside the C99 standard) to *really* learn C.
<snipped>


I compiled your program using gcc-2.95 and executed it.
It works just fine if that comforts you :)
-Anjali
 
A

Alan Balmer

I have done some further research on this, and I have discovered that if
I start a new instance of the shell, it runs just dandy the first time,
but subsequent runs return to the prompt without allowing any input.
From the viewpoint of comp.lang.c, you program is fine ;-) So, the
problem must be something in your environment. You might want to post
the question on a newsgroup which deals with whatever implementation
you're working with. <OT> How does your implementation define end of
file on your stdin (the terminal, I presume)? Is something causing an
EOF to be in the input buffer after the first execution? gdb is
probably starting a brand-new shell for each execution.
 
C

Chris Readle

Alan said:
From the viewpoint of comp.lang.c, you program is fine ;-) So, the
problem must be something in your environment. You might want to post
the question on a newsgroup which deals with whatever implementation
you're working with. <OT> How does your implementation define end of
file on your stdin (the terminal, I presume)? Is something causing an
EOF to be in the input buffer after the first execution? gdb is
probably starting a brand-new shell for each execution.

I've come to that same conclusion myself, so I've been using one term to
compile and then starting another one to run the freshly compiled
executable.

As it turns out from further research, gdb exhibits the same behaviour
if I try to run the program multiple times from within the same gdb
session. I'm going to fire the code over to one of my other platforms
and see if it does the same thing there, which might indicate a weakness
with my compiler (gcc on both platforms).

Anyway, thanks for the help, even though it lead into OT territory.

crr
 
P

Peter Nilsson

Jack Klein said:
Does your input contain a newline? In C it is implementation defined
whether the final line of output to a text stream requires a final
'\n' or not.

This aspect is not limited to output files. 7.19.2p2 says...

A text stream is an ordered sequence of characters composed into lines,
each line consisting of zero or more characters plus a terminating new-
line character. Whether the last line requires a terminating new-line
character is implementation-defined. Characters may have to be added,
^^^^****^^^^^^
altered, or deleted on input and output to conform to differing
^^^^^^^^^^^^^^^^
conventions for representing text in the host environment. ...

I take that to mean that if an implementation does indeed require said new-line, it will
either insert it or otherwise change the stream so that the last line is new-line
terminated.
Some implementations will not output the final line of
text to the display device if it does not end in a newline.

As far as ISO C is concerned, stdout is a stream like any other and the program
successfully copies the portion of stdin input that constitutes a text stream.

If the program adds a new-line, then it's adding an extranious character that was not
present in the text portion of stdin. If that particular correction needs to be made, then
the implementation is responsible for doing that. 7.19.2 says so IMO.

If it's a QoI issue then, given the input and output applicability of 7.19.2, consider...

#include <stdio.h>

int main(void)
{
int c1 = getchar();
int c2 = getchar();

if (c1 != '\n' && c1 != EOF && c2 == EOF)
{
puts("Has a text line been read or not?");
puts("");
puts("Have I already invoked UB on some implementations");
puts("which require a final new-line for input streams?");
}

return 0;
}
 
J

Joe Wright

Chris said:
Ok, I've just recently finished a beginning C class and now I'm working
through K&R2 (alongside the C99 standard) to *really* learn C.

So anyway, I'm working on an exercise in chapter one which give me
strange behavior. Here is the code I've written:
/******************************************************************************

* K&R2 Exercise 1-9
* Write a program to copy its input to its output, replacing strings of
blanks
* with a single blank.
******************************************************************************/

#include <stdio.h>

int main(void) {

int c= 0, lastc= 0;

while((c= getchar()) != EOF) {

if (c == ' ') {
if (lastc != ' ') {//if c *is* a space and lastc is
putchar(c);//*not* a space, print the char
lastc= c;
}//end inner if
}//end outer if

if (c != ' ') {//if c isn't a space don't worry about it
putchar(c);
lastc =c;
}//end if
}//end while

return 0;
}
I just did it this way..

#include <stdio.h>
int main(void) {
int c, last = 0;
while ((c = getchar()) != EOF) {
if (!(c == ' ' && c == last))
putchar(c);
last = c;
}
return 0;
}
The problem I'm having is that when I run the program, I get no
execution, just returned to a prompt. However, when I run gdb on it
(even if I just "run" the program within gdb) it works, and even does
what I expected it to. Can anyone explain this one to me?

crr

Without redirecting a file to it, the program should block on
getchar(), buffering anything you type up to newline and looping in
the while until you 'type' EOF.
 
C

Chris Readle

Joe said:
#include <stdio.h>
int main(void) {
int c, last = 0;
while ((c = getchar()) != EOF) {
if (!(c == ' ' && c == last))
putchar(c);
last = c;
}
return 0;
}

Yeah, I did it this way first as well, til I realized that we hadn't
covered the logical AND operator yet, so I went back and redid it.

It seems as though the Windows shell is storing the EOF on top of the
call stack or something, and this is causing my code to run only once on
the Windows side, and then never again unless I invoke a new shell.
On my FreeBSD box it runs fine multiple times.

crr
 
J

Joe Wright

Chris said:
Yeah, I did it this way first as well, til I realized that we hadn't
covered the logical AND operator yet, so I went back and redid it.

It seems as though the Windows shell is storing the EOF on top of the
call stack or something, and this is causing my code to run only once on
the Windows side, and then never again unless I invoke a new shell. On
my FreeBSD box it runs fine multiple times.

crr

Just trying to make it simple..

#include <stdio.h>
int main(void) {
int c, last = 0;
while ((c = getchar()) != EOF) {
if (last != ' ')
putchar(c);
else if (c != ' ')
putchar(c);
last = c;
}
return 0;
}
 

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,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top