Q: Line Counting, K&R sec. 1.5.3 on OS X

M

Mo Geffer

Greetings:

I have a question about the output of the sample program in section
1.5.3 Line Counting of K&R, Second Edition.

Here's the program:
/****************************************/
#include <stdio.h>

/* count lines in input */
main()
{
int c, nl;

nl = 0;
while ((c = getchar()) != EOF)
if (c == '\n')
++nl;
printf("%d\n", nl);
}
/****************************************/

Here's my session running the program:
/****************************************/
G4:~/c jeff$ ./linecnt
jeff
tom
2D
G4:~/c jeff$
/****************************************/

After typing 'tom' I hit <return> then type CTRL-D. The '2' is correct
but what's with the 'D'??

I ran the same program on both an OS X machine (gcc v. 3.3) and an
OpenBSD 3.3 (gcc 2.95) machine and got the same results.

So, again, what's the 'D' all about?

BTW, when I changed 'int' to 'float' and changed '%d' to '%f' the D
stopped showing up.

Thanks!
 
B

Barry Margolin

Mo Geffer said:
Greetings:

I have a question about the output of the sample program in section
1.5.3 Line Counting of K&R, Second Edition.

Here's the program:
/****************************************/
#include <stdio.h>

/* count lines in input */
main()
{
int c, nl;

nl = 0;
while ((c = getchar()) != EOF)
if (c == '\n')
++nl;
printf("%d\n", nl);
}
/****************************************/

Here's my session running the program:
/****************************************/
G4:~/c jeff$ ./linecnt
jeff
tom
2D
G4:~/c jeff$
/****************************************/

After typing 'tom' I hit <return> then type CTRL-D. The '2' is correct
but what's with the 'D'??

I ran the same program on both an OS X machine (gcc v. 3.3) and an
OpenBSD 3.3 (gcc 2.95) machine and got the same results.

So, again, what's the 'D' all about?

That was the operating system's terminal driver echoing "^D" when you
typed Control-D; it then moved the cursor to the beginning of the line.
Then the program displayed "2", which overwrote the "^" in "^D".
 
M

Mo Geffer

Barry Margolin said:
That was the operating system's terminal driver echoing "^D" when you
typed Control-D; it then moved the cursor to the beginning of the line.
Then the program displayed "2", which overwrote the "^" in "^D".

Yikes!! Is there a way to "fix" this? Is this BSD-related (Mac OS X and
OpenBSD)?
 
C

CBFalconer

Mo said:
Greetings:

I have a question about the output of the sample program in section
1.5.3 Line Counting of K&R, Second Edition.

Here's the program:
/****************************************/
#include <stdio.h>

/* count lines in input */
main()
{
int c, nl;

nl = 0;
while ((c = getchar()) != EOF)
if (c == '\n')
++nl;
printf("%d\n", nl);
}
/****************************************/

Here's my session running the program:
/****************************************/
G4:~/c jeff$ ./linecnt
jeff
tom
2D
G4:~/c jeff$
/****************************************/

After typing 'tom' I hit <return> then type CTRL-D. The '2' is correct
but what's with the 'D'??

I ran the same program on both an OS X machine (gcc v. 3.3) and an
OpenBSD 3.3 (gcc 2.95) machine and got the same results.

So, again, what's the 'D' all about?

BTW, when I changed 'int' to 'float' and changed '%d' to '%f' the D
stopped showing up.

I think you have run into some of the few failings in K&R.
Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.
 
K

Kieran Simkin

As mentioned by Barry, this problem is not actually a problem, your terminal
will echo ^D as the character for control+D. Although this behaviour is
operating system specific, it's not confined to BSD. You should probably not
attempt to fix this "problem" as that would require mutilating your termcap
or some other such nasty hack. Either way, this is off-topic. The best
solution is to add a "\n" before printing anything after receiving an EOF,
resulting in the ^D being placed on a line on its own and not interfering
with your result output. I was actually under the impression UNIX did this
for you, but it appears I'm just used to other people's code doing it. I've
learned something by lurking :)

--


~Kieran Simkin
Digital Crocus
http://digital-crocus.com/
 
D

Darrell Grainger

Just a side note about your program. If you do not specific a return type
for a function it defaults to int. It does not default to void as many
people seem to assume. This means your program assumes main() returns an
int but you have no return statement.

There are two solutions. The first is to change "main()" to "void main()".
The second is to add a "return 0;" to the end of the function. The first
will cause undefined behaviour so I always go for the second solution.

Are you using the first edition of The C Programming Language? The second
edition should say "ANSI" on the cover. The first edition does assume a
main() without an explicit return type has no return type but it pre-dates
the keyword void and the ANSI/ISO standard.
Yikes!! Is there a way to "fix" this? Is this BSD-related (Mac OS X and
OpenBSD)?

You could always do something like:

printf("\n%d\n", nl);

You will still see the ^D on the terminal output but the results will
print on a seperate line.
 
M

Mo Geffer

"Kieran Simkin said:
As mentioned by Barry, this problem is not actually a problem, your terminal
will echo ^D as the character for control+D. Although this behaviour is
operating system specific, it's not confined to BSD. You should probably not
attempt to fix this "problem" as that would require mutilating your termcap
or some other such nasty hack. Either way, this is off-topic. The best
solution is to add a "\n" before printing anything after receiving an EOF,
resulting in the ^D being placed on a line on its own and not interfering
with your result output. I was actually under the impression UNIX did this
for you, but it appears I'm just used to other people's code doing it. I've
learned something by lurking :)

--


~Kieran Simkin
Digital Crocus
http://digital-crocus.com/

<snip>

Okay, I went with Kieran's solution. At least my output makes sense now.

Thanks all!!
 
B

Barry Margolin

CBFalconer said:
I think you have run into some of the few failings in K&R.
Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.

Do you have any real reason to believe this will solve his problem, or
are you just posting to see yourself in print?
 
M

Mo Geffer

Just a side note about your program. If you do not specific a return type
for a function it defaults to int. It does not default to void as many
people seem to assume. This means your program assumes main() returns an
int but you have no return statement.

There are two solutions. The first is to change "main()" to "void main()".
The second is to add a "return 0;" to the end of the function. The first
will cause undefined behaviour so I always go for the second solution.

Are you using the first edition of The C Programming Language? The second
edition should say "ANSI" on the cover. The first edition does assume a
main() without an explicit return type has no return type but it pre-dates
the keyword void and the ANSI/ISO standard.

I'm using the second edition.
You could always do something like:

printf("\n%d\n", nl);

You will still see the ^D on the terminal output but the results will
print on a seperate line.

Yup, that's what I decided to go with.

Thanks!
 
C

CBFalconer

Barry said:
Do you have any real reason to believe this will solve his problem,
or are you just posting to see yourself in print?

Since I do not have his exact system, I obviously don't know
whether that will solve his problem. Others have come up with
good explanations. However you obviously don't believe that the
code should be made conformant before looking for system
peculiarities. Let me encourage you in writing and using code
whose behavious is undefined. But please mark those efforts
clearly, so I and others can avoid them like the plague.
 
B

Barry Margolin

CBFalconer said:
Since I do not have his exact system, I obviously don't know
whether that will solve his problem. Others have come up with
good explanations. However you obviously don't believe that the
code should be made conformant before looking for system
peculiarities. Let me encourage you in writing and using code
whose behavious is undefined. But please mark those efforts
clearly, so I and others can avoid them like the plague.

I certainly have nothing against code being written properly, but I
don't believe in misleading posts. Although the standard allows for
arbitrary behavior of non-conforming programs, any experienced
programmer knows what kinds of misbehaviors are actually likely in real
systems.

It's certainly a good idea to write conformant code, and if you'd said
something like "It probably won't solve the specific problem you asked
for, but you need to fix the following mistakes" I wouldn't have had any
problem. But please don't pretend that you thought that making the code
conformant would change the terminal driver's echoing of "^D".
 
M

Michael Vilain

CBFalconer said:
I think you have run into some of the few failings in K&R.
Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.

Just as a point of order, I sorta take K&R as being the equivalent of
"my grandfather's C textbook". It probably contains things in it that
are rather "old fashioned" as Falconer pointed out. Hence, most people
post about "K&R"-style C vs. ANSI C when talking about C compilers.

[I'm _not_ an evil developer, but I understand where they come from...]
 
M

Mo Geffer

"Michael Vilain said:
CBFalconer said:
I think you have run into some of the few failings in K&R.
Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.

Just as a point of order, I sorta take K&R as being the equivalent of
"my grandfather's C textbook". It probably contains things in it that
are rather "old fashioned" as Falconer pointed out. Hence, most people
post about "K&R"-style C vs. ANSI C when talking about C compilers.

[I'm _not_ an evil developer, but I understand where they come from...]

So which textbook would you recommend if not K&R?
 
A

August Derleth

Michael Vilain said:
CBFalconer said:
I think you have run into some of the few failings in K&R.
Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.

Just as a point of order, I sorta take K&R as being the equivalent of
"my grandfather's C textbook". It probably contains things in it that
are rather "old fashioned" as Falconer pointed out. Hence, most people
post about "K&R"-style C vs. ANSI C when talking about C compilers.

[I'm _not_ an evil developer, but I understand where they come from...]

So which textbook would you recommend if not K&R?

The second edition of K&R, the one that focuses on ANSI C. Commonly
referred to as K&R2 around here.

Most printings of K&R2 advertise their ANSI-compliance right on the cover
in big, red letters. Plus, copies of the first edition of K&R are pretty
much confined to the private libraries of old farts and underfunded
public/college libraries. So I think it's safe to say that K&R2 has
superseded K&R in every important respect.

(Note that K&R2 was written significantly before the newest standard, C99.
Most people don't think this is a problem since most compilers don't
(fully) support C99 anyway.)
 
C

CBFalconer

Mo said:
Michael Vilain said:
CBFalconer said:
I think you have run into some of the few failings in K&R.
Replace "main()" with "int main(void)", and add "return 0;" before
the final '}'. This should avoid undefined behaviour everywhere.

Just as a point of order, I sorta take K&R as being the equivalent
of "my grandfather's C textbook". It probably contains things in
it that are rather "old fashioned" as Falconer pointed out. Hence,
most people post about "K&R"-style C vs. ANSI C when talking about
C compilers.

[I'm _not_ an evil developer, but I understand where they come
from...]

So which textbook would you recommend if not K&R?

I think we all recommend K & R. However, unlike some of us who
will remain nameless, they are not perfect.
 
S

Steven Fisher

August Derleth said:
The second edition of K&R, the one that focuses on ANSI C. Commonly
referred to as K&R2 around here.

From the original post:

"I have a question about the output of the sample program in section
1.5.3 Line Counting of K&R, Second Edition."
 
A

August Derleth

From the original post:

"I have a question about the output of the sample program in section
1.5.3 Line Counting of K&R, Second Edition."

Oh, sorry. I was only reading the post where the differences between K&R C
and ANSI-C were mentioned.

I would still recommend K&R2, BTW. ;)
 
S

Steven Fisher

August Derleth said:
Oh, sorry. I was only reading the post where the differences between K&R C
and ANSI-C were mentioned.

Do you have your K&R 2e in front of you? Is the program in question
still listed that way?

I don't have mine here, but I don't remember seeing that flaw. I should
have noticed... :)
 
C

CBFalconer

Steven said:
Do you have your K&R 2e in front of you? Is the program in
question still listed that way?

Yes and yes. Not in the errata as of roughly a year ago either.
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top