K&R 1.5.1 exercise

M

Merrill & Michele

It's very difficult to do an exercise with elementary tools. It took me
about fifteen minutes to get exercise 1-7:
#include <stdio.h>

int main(int orange, char **apple)
{
int c;
c=-5;
while(c != EOF )
{
c++;
}
printf("%d\t",c);
printf("%d\t",EOF);
return (0);
}
Since my printf's agree that window's EOF is Hamilton's (ijk)^2, I think
it's right.

Exercise 1-6 is giving me dyspepsia. This compiles and links but does not
behave according to my wishes:
#include <stdio.h>

int main(int orange, char **mango)
{
int c;
c=(getchar() != EOF);
printf("%d\t",c);
return (0);
}

I'm looking for a 0 or 1 when I peck randomly at the keyboard, and am at my
wit's end, as I also seem to be unable to debug. Remember, if you kick a
man when he's down, you better make sure he either stays down or he isn't 2
meters tall, 114 kg. ++Thanks. MPJ
 
C

Chris Barts

It's very difficult to do an exercise with elementary tools. It took me
about fifteen minutes to get exercise 1-7:
#include <stdio.h>

int main(int orange, char **apple)

Why the bizarre names for these variables? argc and argv, respectively,
have served nearly all C programmers very well.
{
int c;
c=-5;
while(c != EOF )
{
c++;
}

This is trivial enough. You should allow for the possibility for EOF to be
equal to a value like INT_MIN, in which case this program could run a
very, very long time. (Assuming it can wrap around from INT_MAX to INT_MIN
at all, and do so without crashing.)
printf("%d\t",c);
printf("%d\t",EOF);

You probably want a newline, not a tab, in at least one of these
statements.
return (0);
}
Since my printf's agree that window's EOF is Hamilton's (ijk)^2, I think
it's right.

It will be right, assuming EOF >= -5 on your machine.
Exercise 1-6 is giving me dyspepsia. This compiles and links but does not
behave according to my wishes:
#include <stdio.h>

int main(int orange, char **mango)
{
int c;
c=(getchar() != EOF);

This is the problem, I think. You're expecting a coherent result from a
very strange statement.
printf("%d\t",c);

ITYM printf("%d\n",c);
return (0);
}

I'm looking for a 0 or 1 when I peck randomly at the keyboard, and am at my
wit's end, as I also seem to be unable to debug.

I don't know that either value is guaranteed by the Standard, or
reasonably expectable on any machines.
Remember, if you kick a
man when he's down, you better make sure he either stays down or he isn't 2
meters tall, 114 kg. ++Thanks. MPJ

You'll get no kicks from me.
 
R

Richard Bos

Merrill & Michele said:
It's very difficult to do an exercise with elementary tools.

If you mean the exercises from K&R, I found it no problem at all doing
most of them using tools as elementary as paper and pen. Then again...
int main(int orange, char **apple)

....I wasn't wilfully perverse, so maybe, just maybe, if you start taking
it seriously, you would get a bit farther?

Richard
 
D

Dan Pop

In said:
It's very difficult to do an exercise with elementary tools. It took me
about fifteen minutes to get exercise 1-7:
#include <stdio.h>

int main(int orange, char **apple)
{
int c;
c=-5;
while(c != EOF )
{
c++;
}
printf("%d\t",c);
printf("%d\t",EOF);
return (0);
}
Since my printf's agree that window's EOF is Hamilton's (ijk)^2, I think
it's right.

Nope, it isn't. Your while loop will eventually cause integer overflow,
which is undefined behaviour in C. Furthermore, it is entirely irrelevant
to your problem, whose solution is as simple as:

#include <stdio.h>

int main()
{
printf("%d\n", EOF);
return 0;
}
Exercise 1-6 is giving me dyspepsia. This compiles and links but does not
behave according to my wishes:
#include <stdio.h>

int main(int orange, char **mango)
{
int c;
c=(getchar() != EOF);
printf("%d\t",c);
return (0);
}

I'm looking for a 0 or 1 when I peck randomly at the keyboard, and am at my
wit's end, as I also seem to be unable to debug.

Your program is almost correct. Replace \t by \n and it is fully correct.
It would have been even better if you used a loop, with getchar() != EOF
evaluating to 0 as the exit condition, but it works even in your version,
if you understand that stdin, when connected to the terminal, is line
buffered. So, nothing will happen until you press the Return/Enter key.
Your platform may require it even after the eof key. After that, your
getchar() call will return the code of the first character you have typed
or EOF if you have typed the corresponding character for your platform
(CTRL-Z for DOS/Windows, CTRL-D for Unix). So, you can expect a 1 as
output most of the time, unless the first character you have typed was
the one generating an end of file condition.

This program is much easier to work with if you use a loop and redirect
stdin from a file:

fangorn:~/tmp 146> cat input
12345
fangorn:~/tmp 147> cat test.c
#include <stdio.h>

int main()
{
int cond;

while ((cond = getchar() != EOF) == 1) printf("%d ", cond);
printf("%d\n", cond);
return 0;
}
fangorn:~/tmp 148> gcc test.c
fangorn:~/tmp 149> ./a.out <input
1 1 1 1 1 1 0

The input file contains 6 characters: the five visible ones (12345)
and the newline character. For each of them, the expression
getchar() != EOF evaluates to 1 and a 1 is displayed in the program
output. The seventh getchar() call generates and end of file condition
on the stream and it returns EOF. At that point, the expression
getchar() != EOF evaluates to 0 and the while loop is terminated.
The corresponding value of the expression is displayed, followed by
the mandatory newline character.

Dan
 
D

Dan Pop

In said:
This is the problem, I think. You're expecting a coherent result from a
very strange statement.

Did you bother reading Exercise 1-6? There is nothing strange here,
except the misleading name of the variable. It leads the experienced
programmer to believe that the idiomatic (c = getchar()) != EOF was
somehow intended, but this is not the case: it is indeed the value of
getchar() != EOF that is the focus of this exercise.

Dan
 
D

Dan Pop

In said:
If you mean the exercises from K&R, I found it no problem at all doing
most of them using tools as elementary as paper and pen. Then again...

You missed his point: elementary C programming elements, not an elementary
execution environment.
...I wasn't wilfully perverse, so maybe, just maybe, if you start taking
it seriously, you would get a bit farther?

Since the program did not make *any* use of the main parameters, I fail to
see your point (if any).

Dan
 
M

Merrill & Michele

It's very difficult to do an exercise with elementary tools. It took me
Dan wrote:
Nope, it isn't. Your while loop will eventually cause integer overflow,
which is undefined behaviour in C. Furthermore, it is entirely irrelevant
to your problem, whose solution is as simple as:

#include <stdio.h>

int main()
{
printf("%d\n", EOF);
return 0;
}

Thanks all for replies. Mr. Pop is correct that his shortened version of my
prog does indeed yield -1, but I liked the idea of trying to find the
appropriate answer with a while{}. Would Mr. Pop have the same criticism if
one began the loop with Mr. Barts' (I know I got your 's' this time, but did
I get the possessive correct?) INT_MIN suggestion, incremented in the usual
fashion, and it were stipulated that an EOF had indeed been #defined as an
int?
Your program is almost correct. Replace \t by \n and it is fully correct.
It would have been even better if you used a loop, with getchar() != EOF
evaluating to 0 as the exit condition, but it works even in your version,
if you understand that stdin, when connected to the terminal, is line
buffered. So, nothing will happen until you press the Return/Enter key.
Your platform may require it even after the eof key. After that, your
getchar() call will return the code of the first character you have typed
or EOF if you have typed the corresponding character for your platform
(CTRL-Z for DOS/Windows, CTRL-D for Unix). So, you can expect a 1 as
output most of the time, unless the first character you have typed was
the one generating an end of file condition.

This program is much easier to work with if you use a loop and redirect
stdin from a file:

I too have other means of getting data to a prog and avoid the keyboard
during runtime like the plague, but the point of this exercise is to force
us into this straightjacket.
fangorn:~/tmp 146> cat input
12345
fangorn:~/tmp 147> cat test.c
#include <stdio.h>

int main()
{
int cond;

while ((cond = getchar() != EOF) == 1) printf("%d ", cond);
printf("%d\n", cond);
return 0;
}
fangorn:~/tmp 148> gcc test.c
fangorn:~/tmp 149> ./a.out <input
1 1 1 1 1 1 0
Among other things, I don't know whether your 'cat's are like my 'orange's.
In short, I've never touched Unix.
The input file contains 6 characters: the five visible ones (12345)
and the newline character. For each of them, the expression
getchar() != EOF evaluates to 1 and a 1 is displayed in the program
output. The seventh getchar() call generates and end of file condition
on the stream and it returns EOF. At that point, the expression
getchar() != EOF evaluates to 0 and the while loop is terminated.
The corresponding value of the expression is displayed, followed by
the mandatory newline character.

The following sentence immediately precedes ex. 1-6: "This has the effect
of setting c to 0 or 1, depending on whether or not the call of getchar
encountered EOF." The 'this' in reference is exactly the first line of my
code after declarations. I'm still not getting results. I think I remember
Heathfield made some remark about either putchar or getchar, but I can't
crack open that book, currently five feet from my knee, as I am going
through K&R sequentially. MPJ
Output:
http://home.comcast.net/~beckjensen/cstuff4.htm
 
M

Michael Mair

Merrill said:
Thanks all for replies. Mr. Pop is correct that his shortened version of my
prog does indeed yield -1, but I liked the idea of trying to find the
appropriate answer with a while{}. Would Mr. Pop have the same criticism if
one began the loop with Mr. Barts' (I know I got your 's' this time, but did
I get the possessive correct?) INT_MIN suggestion, incremented in the usual
fashion, and it were stipulated that an EOF had indeed been #defined as an
int?

He would probably point out that your way is pointless and that you
should start engaging the gray stuff between your ears... However,
that is not mine to say.
If you would bother to read _and_ try to understand everything he says,
you would find out that the problem with the signed integer overflow
then still would not be resolved.
As EOF is a constant negative integer, you can start at INT_MIN and
stop at 0. If you do not want to do so, you have to make sure that c
is not increased when it has the value INT_MAX as this leads to
undefined behaviour.


Once more: Give us the text -- not everyone has a copy right
next to his hand...
not



I too have other means of getting data to a prog and avoid the keyboard
during runtime like the plague, but the point of this exercise is to force
us into this straightjacket.

It is not.
Among other things, I don't know whether your 'cat's are like my 'orange's.
In short, I've never touched Unix.

cat <file> essentially reads the file <file> and outputs it to stdout.
The line "./a.out <input" executes the program "./a.out" and redirects
"input" to stdin for this program.

The following sentence immediately precedes ex. 1-6: "This has the effect
of setting c to 0 or 1, depending on whether or not the call of getchar
encountered EOF." The 'this' in reference is exactly the first line of my
code after declarations. I'm still not getting results. I think I remember
Heathfield made some remark about either putchar or getchar, but I can't
crack open that book, currently five feet from my knee, as I am going
through K&R sequentially. MPJ
Output:
http://home.comcast.net/~beckjensen/cstuff4.htm

To me, it seems that your main trouble is your programming environment.
Perhaps it would be better to use more basic tools and an environment
you can understand more easily.
This has been pointed out to you somewhere else, too.

Apart from that, if you follow the steps Dan pointed out, everything
should work fine.
Note that you get stuff from stdin via _any_ of the standard C input
functions only after you hit the return key.


Cheers
Michael
 
D

Dan Pop

In said:
Thanks all for replies. Mr. Pop is correct that his shortened version of my
prog does indeed yield -1, but I liked the idea of trying to find the
appropriate answer with a while{}. Would Mr. Pop have the same criticism if
one began the loop with Mr. Barts' (I know I got your 's' this time, but did
I get the possessive correct?) INT_MIN suggestion, incremented in the usual
fashion, and it were stipulated that an EOF had indeed been #defined as an
int?

EOF is guaranteed to have the type int and a negative value. If you start
at INT_MIN you can't miss it before reaching 0. No undefined behaviour
in sight.

What happens *after* you press the Return/Enter key, as I have asked you
to do?

Answer: you'll a get a 1 or 0 displayed, but you may never have
a chance to see it, if your IDE automatically closes your console
window after program termination. If this is the case, indeed, generate
the EXE file and run it by hand in a standalone console window.

The C beginner using K&R2 is better served by a command line compiler than
by any kind of IDE. All the examples and exercises have been designed
with a command line environment in mind.

Dan
 
M

Merrill & Michele

He would probably point out that your way is pointless and that you
should start engaging the gray stuff between your ears... However,
that is not mine to say.
If you would bother to read _and_ try to understand everything he says,
you would find out that the problem with the signed integer overflow
then still would not be resolved.
As EOF is a constant negative integer, you can start at INT_MIN and
stop at 0. If you do not want to do so, you have to make sure that c
is not increased when it has the value INT_MAX as this leads to
undefined behaviour.

Mr. Pop does not require your input to disparage. You are incorrect that I
do not read and try to understand. You are further incorrect to claim K&R2
#defines EOF as a negative int. In the chapter I just read, he says it
can't be an int that could otherwise be a char. Demnach, EOF could be
between CHAR_MAX and INT_MAX. Furthermore, I can't remember if I have a
logical OR yet. Reflecting on it, I could use a for and increment from
INT_MIN to INT_MAX and do just fine, but this does not follow the
development.
Once more: Give us the text -- not everyone has a copy right
next to his hand...
Schade.
It is not.
It's amazing to announce the intent of an exercise of a book that you don't
have in hand.

cat <file> essentially reads the file <file> and outputs it to stdout.
The line "./a.out <input" executes the program "./a.out" and redirects
"input" to stdin for this program.
Good to know.
To me, it seems that your main trouble is your programming environment.
Perhaps it would be better to use more basic tools and an environment
you can understand more easily.
This has been pointed out to you somewhere else, too.

Apart from that, if you follow the steps Dan pointed out, everything
should work fine.
Note that you get stuff from stdin via _any_ of the standard C input
functions only after you hit the return key.

My programming environment is definitely austere. I haven't found an
instance of where it has not performed properly given ANSI-compliant C. My
question then is, does the following code, when executed, take keystrokes
and put either a zero or a one as output depending on whether the keystroke
is, respectively, EOF or anything else?
#include <stdio.h>

int main(int orange, char **mango)
{
int c;
c=(getchar() != EOF);
printf("%d\n",c);
return (0);
}
I'll address some form of upgrade after I plough through K&R. MPJ
 
M

Michael Mair

Hello,
of my


criticism if



Mr. Pop does not require your input to disparage.

Certainly not -- which is exactly what I said.
You are incorrect that I
do not read and try to understand.

Well, then why do you not just do exactly what he suggests?
And then come back and ask questions? Instead of not doing
it and come back.
You are further incorrect to claim K&R2
#defines EOF as a negative int.

I did not claim that -- this was just FYI.
In the chapter I just read, he says it
can't be an int that could otherwise be a char. Demnach, EOF could be
between CHAR_MAX and INT_MAX.

Right. Which the rest of my statement dealt with.
Furthermore, I can't remember if I have a
logical OR yet.

.... and what does this have to do with it?
Reflecting on it, I could use a for and increment from
INT_MIN to INT_MAX and do just fine,

Which is what I suggest.
> but this does not follow the development.
???



Schade.

I _do_ have a copy. But not everyone has one and not necessarily
at the place where he reads your message from.

It's amazing to announce the intent of an exercise of a book that you don't
have in hand.

It would be if I had not.

My programming environment is definitely austere. I haven't found an
instance of where it has not performed properly given ANSI-compliant C.

Yes. See Dan Pop's reply for reasons against it as I am tired of
reiterating what you already have been told more than twice.
My
question then is, does the following code, when executed, take keystrokes
and put either a zero or a one as output depending on whether the keystroke
is, respectively, EOF or anything else?
#include <stdio.h>

int main(int orange, char **mango)
{
int c;
c=(getchar() != EOF);
printf("%d\n",c);
return (0);
}

It does. If you would hit the return key after entering something
producing EOF or not -- as Dan Pop and I have told you -- you would
find out for yourself.

I'll address some form of upgrade after I plough through K&R. MPJ

Not necessary.

I refer you to Dan Pop's reply further down the thread. Perhaps
his way of telling it to you will shed more light on it for you.


It might be a Good Idea to get a "naked" editor not integrated
in an IDE and a compiler either for DOS or Windows or to get
CygWin and learn things from scratch.


-- Michael
 
D

Dan Pop

In said:
question then is, does the following code, when executed, take keystrokes
and put either a zero or a one as output depending on whether the keystroke
is, respectively, EOF or anything else?
#include <stdio.h>

int main(int orange, char **mango)
{
int c;
c=(getchar() != EOF);
printf("%d\n",c);
return (0);
}

I have already explained you *exactly* what this program does. The
behaviour is less than obvious when stdin is connected to a terminal
because the getchar() call won't return until the user presses the
Return/Enter key (on some platforms it may return as soon as the eof
key is pressed). Once the user has pressed the Return key, the program
will display a 1 or a 0, depending on what was the first key pressed by
the user.

fangorn:~/tmp 206> cat test.c
#include <stdio.h>

int main(int orange, char **mango)
{
int c;
c=(getchar() != EOF);
printf("%d\n",c);
return (0);
}
fangorn:~/tmp 207> gcc test.c
fangorn:~/tmp 208> ./a.out
foo <------ my input
1
fangorn:~/tmp 209> ./a.out
0

In the second invocation, I merely pressed the eof key when the program
was expecting input. On my platform, no Return key was needed in this
case, but other platforms require it.

The behaviour of such programs is easier to understand if stdin is
redirected:

fangorn:~/tmp 213> ./a.out < /dev/zero
1
fangorn:~/tmp 214> ./a.out < /dev/null
0

/dev/zero is a device supplying an infinite stream of null bytes, while
/dev/null reports an end of file condition when read.

Dan
 
M

Merrill & Michele

MPJ said:
Dan wrote:
EOF is guaranteed to have the type int and a negative value. If you start
at INT_MIN you can't miss it before reaching 0. No undefined behaviour
in sight.
What happens *after* you press the Return/Enter key, as I have asked you
to do?

Answer: you'll a get a 1 or 0 displayed, but you may never have
a chance to see it, if your IDE automatically closes your console
window after program termination. If this is the case, indeed, generate
the EXE file and run it by hand in a standalone console window.

The C beginner using K&R2 is better served by a command line compiler than
by any kind of IDE. All the examples and exercises have been designed
with a command line environment in mind.
Yeah, I missed it. The IDE was fine; the monkey running it, well .... I
can create the command line and would likely be better served by another
compiler. I'm not single-minded like George Bush in that I have single
thought in my head. I'm single-minded in that I don't change horses or
focus until I have to. MPJ
 

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

Beginner at c 0
K&R Exercise 1-21: entab 10
K$R xrcise 1-13 (histogram) 4
K&R2, exercise 5-4, strend(s,t) 15
K&R2, exercise 4-2 12
K&R 1-24 15
K&R 5-1 9
K&R2, exercise 5.5 7

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top