Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #60434 > unrolled thread
| Started by | G G <gdotone@gmail.com> |
|---|---|
| First post | 2015-04-19 09:50 -0700 |
| Last post | 2015-04-23 07:59 -0700 |
| Articles | 20 — 9 participants |
Back to article view | Back to comp.lang.c
can this be done recursively G G <gdotone@gmail.com> - 2015-04-19 09:50 -0700
Re: can this be done recursively Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-04-19 21:14 +0100
Re: can this be done recursively G G <gdotone@gmail.com> - 2015-04-19 14:20 -0700
Re: can this be done recursively Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-04-19 16:32 -0400
Re: can this be done recursively G G <gdotone@gmail.com> - 2015-04-19 14:25 -0700
Re: can this be done recursively Keith Thompson <kst-u@mib.org> - 2015-04-19 14:09 -0700
Re: can this be done recursively G G <gdotone@gmail.com> - 2015-04-19 14:35 -0700
Re: can this be done recursively jt@toerring.de (Jens Thoms Toerring) - 2015-04-19 22:57 +0000
Re: can this be done recursively G G <gdotone@gmail.com> - 2015-04-20 04:30 -0700
Re: can this be done recursively Richard Heathfield <rjh@cpax.org.uk> - 2015-04-20 12:49 +0100
Re: can this be done recursively G G <gdotone@gmail.com> - 2015-04-20 05:28 -0700
Re: can this be done recursively jt@toerring.de (Jens Thoms Toerring) - 2015-04-20 13:09 +0000
Re: can this be done recursively G G <gdotone@gmail.com> - 2015-04-22 09:42 -0700
Re: can this be done recursively Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-04-22 10:12 -0700
Re: can this be done recursively James Kuyper <jameskuyper@verizon.net> - 2015-04-22 13:29 -0400
Re: can this be done recursively Ben Bacarisse <ben.lists@bsb.me.uk> - 2015-04-22 20:57 +0100
Re: can this be done recursively James Kuyper <jameskuyper@verizon.net> - 2015-04-22 16:12 -0400
Re: can this be done recursively Ben Bacarisse <ben.lists@bsb.me.uk> - 2015-04-22 23:14 +0100
Re: can this be done recursively James Kuyper <jameskuyper@verizon.net> - 2015-04-22 18:56 -0400
Re: can this be done recursively G G <gdotone@gmail.com> - 2015-04-23 07:59 -0700
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-19 09:50 -0700 |
| Subject | can this be done recursively |
| Message-ID | <b0319922-1b5e-48d2-8cc7-5cd1a5e866e6@googlegroups.com> |
This problem comes from "C How to Program" by Deitel and Deitel
5.18
(Even or Odd) Write a program that inputs a series of integers
and passes them one at a time to function even, which uses the remainder
operator to determine whether an integer is even. The function should
take an integer argument and return 1 if the integer is even and 0
otherwise.
this is from chapter 5, arrays have not been introduced yet, recursion has.
no need to show an answer, i'm just curious.
to solve the problem where it can continuous have input, i used a while loop
and a sentinel.
thanks,
g.
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-04-19 21:14 +0100 |
| Message-ID | <87r3rf7u5d.fsf@bsb.me.uk> |
| In reply to | #60434 |
G G <gdotone@gmail.com> writes: > This problem comes from "C How to Program" by Deitel and Deitel > > 5.18 > > (Even or Odd) Write a program that inputs a series of integers > and passes them one at a time to function even, which uses the remainder > operator to determine whether an integer is even. The function should > take an integer argument and return 1 if the integer is even and 0 > otherwise. > > this is from chapter 5, arrays have not been introduced yet, recursion has. > > no need to show an answer, i'm just curious. Yes, you could write the loop recursively. (You could even write the parity test as a recursive pair of functions though that would be just for fun.) > to solve the problem where it can continuous have input, i used a while loop > and a sentinel. That's almost certainly how the book expects you to do it, though I prefer to avoid sentinels. Simply looping while a number can be read almost always leads to a simpler program. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-19 14:20 -0700 |
| Message-ID | <ab91053e-9a52-49a0-9983-b1baee4ea880@googlegroups.com> |
| In reply to | #60454 |
On Sunday, April 19, 2015 at 4:14:30 PM UTC-4, Ben Bacarisse wrote: > Yes, you could write the loop recursively. (You could even write the > parity test as a recursive pair of functions though that would be just > for fun.) > Ben. that's cool. g.
[toc] | [prev] | [next] | [standalone]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2015-04-19 16:32 -0400 |
| Message-ID | <ShUYw.303241$Lw2.132369@fx30.iad> |
| In reply to | #60434 |
On Sunday April 19 2015 12:50, in comp.lang.c, "G G" <gdotone@gmail.com> wrote: > This problem comes from "C How to Program" by Deitel and Deitel > > 5.18 > > (Even or Odd) Write a program that inputs a series of integers > and passes them one at a time to function even, which uses the > remainder operator to determine whether an integer is even. The > function should take an integer argument and return 1 if the integer > is even and 0 otherwise. > > this is from chapter 5, arrays have not been introduced yet, recursion > has. > > no need to show an answer, i'm just curious. Yes you could use recursion. But the problem is solved easily without recursion, so why bother? > to solve the problem where it can continuous have input, i used a while > loop and a sentinel. That's the way I would do it. How are you inputting your series of integers? Are you using argc & argv[], or are you using stdin, or some other input method? For argc & argv[], you can just loop until reaching argv[argc] (which will be NULL) For the simplest use of stdin, you can loop until EOF -- Lew Pitcher "In Skills, We Trust" PGP public key available upon request
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-19 14:25 -0700 |
| Message-ID | <d00e13c5-fdf1-4af5-aa49-f57c97b496af@googlegroups.com> |
| In reply to | #60455 |
On Sunday, April 19, 2015 at 4:32:57 PM UTC-4, Lew Pitcher wrote: > How are you inputting your series of integers? Are you using argc & argv[], > or are you using stdin, or some other input method? > > For argc & argv[], you can just loop until reaching argv[argc] (which will > be NULL) > > For the simplest use of stdin, you can loop until EOF > -- > Lew Pitcher > "In Skills, We Trust" > PGP public key available upon request in this part of the book the author has not made mention of using argc & arg[] but that would certainly work. i actually ask the user, of the program, if they have another integer they would like to check, if so the program CONTINUEs. so, i use an enumeration, because the author introduces enums in the chapter. thanks, g.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-04-19 14:09 -0700 |
| Message-ID | <87sibvomfh.fsf@kst-u.example.com> |
| In reply to | #60434 |
G G <gdotone@gmail.com> writes:
> This problem comes from "C How to Program" by Deitel and Deitel
>
> 5.18
>
> (Even or Odd) Write a program that inputs a series of integers
> and passes them one at a time to function even, which uses the remainder
> operator to determine whether an integer is even. The function should
> take an integer argument and return 1 if the integer is even and 0
> otherwise.
>
> this is from chapter 5, arrays have not been introduced yet, recursion has.
>
> no need to show an answer, i'm just curious.
>
> to solve the problem where it can continuous have input, i used a while loop
> and a sentinel.
Was there a question in there? I didn't see it.
Using a sentinel value is one reasonable approach. A more general
one is to read as much input as is provided. For example, if you use
scanf("%d", &n);
to read each int value, you can check the value returned by scanf
to determine whether it was able to read an integer value, and quit
if it wasn't. (Read the documentation for scanf for details.)
The user can then signal end of input by typing Control-D on a
UNIX-like system, or Control-Z on Windows.
Using scanf for numeric input has some serious problems (in
particular its behavior is undefined if the input value is out
of range), but it's good enough for a simple program like this.
A more robust solution would be to read lines using fgets() and
then parse them using strtol(). You'll get to that later.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-19 14:35 -0700 |
| Message-ID | <0eda364c-4e80-4711-ba25-1d94e8ab9efb@googlegroups.com> |
| In reply to | #60460 |
Thanks Keith, g.
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2015-04-19 22:57 +0000 |
| Message-ID | <cpiq6uF3kqkU1@mid.uni-berlin.de> |
| In reply to | #60468 |
Do you know that you can call main() recursively? So, to use
recursion, you could do something like
static int even(int n) {
return n % 2 ? 0 : 1;
}
int main(void) {
int n;
if (scanf("%d", &n) != 1)
return 0;
printf( "%d is %s\n", n, even(n) ? "even" : "odd");
return main();
}
There's one snag with using scanf(), though: it's behaviour can be
a bit surprising if the user inputs a number which is too large to
fit into an int. But I guess that's not something you're expected
to consider at that point of the book.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-20 04:30 -0700 |
| Message-ID | <21b34a42-46a6-42c2-bda5-aa8c3486c1b1@googlegroups.com> |
| In reply to | #60434 |
i have a question about the do while( ... ) statement.
This problem is an exercise from Deitel and Deitel, "C How to Program"
/*
5.18 (Even or Odd) Write a program that inputs a series of integers
and passes them one at a time to function even, which uses the remainder
operator to determine whether an integer is even. The function should
take an integer argument and return 1 if the integer is even and 0
otherwise.
*/
/*
This program allows a user to enter an integer, of type int, and test
whether the integer is even or odd.
The program will ask the user if there are more integers that should
be check and continue if the user decides to check more numbers.
*/
#include <stdio.h>
/* enumeration constants for continuing the program */
enum Status { CONTINUE = 1, DONE };
/* function prototype */
int even( int );
int main( void )
{
int number;
enum Status programStatus;
programStatus = CONTINUE;
unsigned int choiceToContinue;
while ( programStatus == CONTINUE )
{
/* prompt user to enter an integer or 0 to end program */
printf( "Enter an integer to determine if it is even or odd : " );
/* read in integer */
scanf( "%d", &number );
if ( even( number ) == 1 )
printf( "\n%d is even\n\n", number );
else
printf( "\n%d is odd\n\n", number );
do
{
/* ask user if there is another number */
printf( "Is there another integer you wish to check? " );
printf( "1 for yes, 2 for no\n" );
/* read in user choice to continue or stop */
scanf( "%d", &choiceToContinue );
}while( (choiceToContinue != 1) && (choiceToContinue != 2) );
if (choiceToContinue == DONE )
programStatus = DONE;
} /* end while ( number ... ) */
return 0;
} /* end main( ... ) */
i have a question. the while statement of the do while statement. why does this
work?
i used
do
{
...
} while( ( choiceToContinue != 1 ) || ( choiceToContinue != 2) )
with the expectation that if the user enter anything other than 1 or 2 (integers) that
the loop would continue to ask the user if they would like to continue
or quit. but that did not work. i replaced the logical or with the logical
and, &&, and it works. why?
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-04-20 12:49 +0100 |
| Message-ID | <mh2p1j$s0d$1@dont-email.me> |
| In reply to | #60510 |
On 20/04/15 12:30, G G wrote:
<snip>
>
> i have a question. the while statement of the do while statement. why does this
> work?
>
> i used
> do
> {
> ...
> } while( ( choiceToContinue != 1 ) || ( choiceToContinue != 2) )
>
> with the expectation that if the user enter anything other than 1 or 2 (integers) that
> the loop would continue to ask the user if they would like to continue
> or quit. but that did not work. i replaced the logical or with the logical
> and, &&, and it works. why?
Consider what this means:
} while( ( choiceToContinue != 1 ) || ( choiceToContinue != 2) )
Let's try to make this do/while terminate by setting choiceToContinue = 0.
Since 0 != 1 is true (0 is indeed not equal to 1), the OR is satisfied,
so the loop continues. Okay, so that didn't work. Let's try setting
choiceToContinue to 1.
1 != 1 is false, so we move to the second part of the OR, where we
discover that 1 != 2 is true, so the loop continues. Okay, so that
didn't work. Let's try setting choiceToContinue to 2.
2 != 1 is true, so the OR is satisfied, and the loop continues.
So far, everything we've tried makes the loop continue.
The only way to make this loop stop is to find a value of
choiceToContinue that is equal to 1 and also equal to 2. If it isn't
equal to at least one of them, the loop will continue, and it's bound to
not be equal to at least one of them.
You asked: Is there another number you wish to check? You asked them to
type in 1 if there was. So why not just do:
} while(choiceToContinue == 1);
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-20 05:28 -0700 |
| Message-ID | <86edc86b-9c97-4611-a94f-ec748d4f8369@googlegroups.com> |
| In reply to | #60514 |
On Monday, April 20, 2015 at 7:49:11 AM UTC-4, Richard Heathfield wrote:
> On 20/04/15 12:30, G G wrote:
>
> <snip>
>
> >
> > i have a question. the while statement of the do while statement. why does this
> > work?
> >
> > i used
> > do
> > {
> > ...
> > } while( ( choiceToContinue != 1 ) || ( choiceToContinue != 2) )
> >
> > with the expectation that if the user enter anything other than 1 or 2 (integers) that
> > the loop would continue to ask the user if they would like to continue
> > or quit. but that did not work. i replaced the logical or with the logical
> > and, &&, and it works. why?
>
>
> Consider what this means:
>
> } while( ( choiceToContinue != 1 ) || ( choiceToContinue != 2) )
>
> Let's try to make this do/while terminate by setting choiceToContinue = 0.
>
> Since 0 != 1 is true (0 is indeed not equal to 1), the OR is satisfied,
> so the loop continues. Okay, so that didn't work. Let's try setting
> choiceToContinue to 1.
>
> 1 != 1 is false, so we move to the second part of the OR, where we
> discover that 1 != 2 is true, so the loop continues. Okay, so that
> didn't work. Let's try setting choiceToContinue to 2.
>
> 2 != 1 is true, so the OR is satisfied, and the loop continues.
>
> So far, everything we've tried makes the loop continue.
>
> The only way to make this loop stop is to find a value of
> choiceToContinue that is equal to 1 and also equal to 2. If it isn't
> equal to at least one of them, the loop will continue, and it's bound to
> not be equal to at least one of them.
>
> You asked: Is there another number you wish to check? You asked them to
> type in 1 if there was. So why not just do:
>
> } while(choiceToContinue == 1);
>
> --
> Richard Heathfield
> Email: rjh at cpax dot org dot uk
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line 4 vacant - apply within
thank you, of course!!!
thanks again
g.
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2015-04-20 13:09 +0000 |
| Message-ID | <cpkc3cFf30tU1@mid.uni-berlin.de> |
| In reply to | #60514 |
Richard Heathfield <rjh@cpax.org.uk> wrote:
> On 20/04/15 12:30, G G wrote:
> <snip>
> >
> > i have a question. the while statement of the do while statement. why does this
> > work?
> >
> > i used
> > do
> > {
> > ...
> > } while( ( choiceToContinue != 1 ) || ( choiceToContinue != 2) )
> >
> > with the expectation that if the user enter anything other than 1 or 2 (integers) that
> > the loop would continue to ask the user if they would like to continue
> > or quit. but that did not work. i replaced the logical or with the logical
> > and, &&, and it works. why?
Another way to tackle this is applying a bit of Boolean algebra
to your condition:
( ( choiceToContinue != 1 ) || ( choiceToContinue != 2 ) )
can obviously also be written as
( ! ( choiceToContinue == 1 ) || ! ( choiceToContinue == 2 ) )
Now
( ! A || ! B ) is the same as ( ! ( A && B ) )
which is often useful to remember when things get a bit complex
(the proof is left to the reader;-) so your condition can be
transformed into
( ! ( ( choiceToContinue == 1 ) && ( choiceToContinue == 2 ) ) )
Since 'choiceToContinue' can never be 1 and 2 at the same time
all the inner stuff is always false. With the negation in front
of it the whole condition is thus always true, so you never get
out of the loop.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-22 09:42 -0700 |
| Message-ID | <e07362d0-5d7e-4243-acc6-bcf384298b69@googlegroups.com> |
| In reply to | #60434 |
I have another question: i'm using os x 10.3.3, and when i do a control-D
the program does not quit. it enters an infinite loop, well, a loop, it seems
as if it is infinite, of course i stop it, using Xcode stop execution button.
shouldn't control-D or control-z halt the execution of the program no matter
what's being read in? i have not disable the control-D as far as i know.
an updated program is below.
/************************************************************************************/
On Sunday, April 19, 2015 at 12:50:17 PM UTC-4, G G wrote:
> This problem comes from "C How to Program" by Deitel and Deitel
5.18
(Even or Odd) Write a program that inputs a series of integers
and passes them one at a time to function even, which uses the remainder
operator to determine whether an integer is even. The function should
take an integer argument and return 1 if the integer is even and 0
otherwise.
/*************************************************************************************/
/*
This program allows the user to enter an integer and checks
whether the integer is positive or negative. The user may
continue checking integers by entering a 'y' or 'Y' when
prompted. To end the program, when prompted, the user may
enter an 'n', or 'N'.
If the user tries to use a contol-D unexpected behavior occurs
using a Mac OS X. (as far as I can tell)
*/
#include <stdio.h>
/* enumeration constants for continuing the program */
enum Status { FINISHED, CONTINUE };
/* enumeration for checking if correct letters where entered */
enum CharStatus { NO, YES };
/* function prototype */
int even( long int );
int main( void )
{
long int number;
char ch;
enum Status programStatus;
enum CharStatus characterOK= YES;
programStatus = CONTINUE;
while ( programStatus == CONTINUE )
{
/* prompt user to enter an integer */
printf( "Enter an integer to determine if it is even or odd : " );
/* read in integer */
scanf( "%ld", &number );
ch = getchar(); /* need to handle the return when pressed */
if ( even( number ) )
printf( "\n%ld is even\n\n", number );
else
printf( "\n%ld is odd\n\n", number );
ch = ' '; /* make sure ch does not contain the \n character */
puts("another number, y for yes, n for no?");
/* allow only y,Y,n or N to control program continuation or termination */
while ( ( (ch = getchar()) != '\n') || (characterOK == NO) )
{
char temp = ch; /* needed because of the return, '\n', character */
switch( temp )
{
case 'y':
case 'Y':
programStatus = CONTINUE;
characterOK = YES;
break;
case 'n':
case 'N':
programStatus = FINISHED;
characterOK = YES;
break;
default:
puts("another number, y for yes, n for no?");
characterOK = NO;
ch = getchar();
ch = ' ';
break;
} /* end switch( temp ) */
} /* end while ( ( (ch = getchar() ... ) */
} /* end while ( programStatus == CONTINUE ) */
return 0;
} /* end main( ... ) */
/********** even( ... ) **********/
int even( long int n )
{
if ( ( n % 2) == 0 ) /* (n % 2)? 1: 0 */
return 1;
else
return 0;
} /* end even( ... ) */
thanks,
g.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-04-22 10:12 -0700 |
| Message-ID | <cd42f377-39ab-4f40-a28c-ddbfd3b473e6@googlegroups.com> |
| In reply to | #60753 |
On Wednesday, April 22, 2015 at 5:42:48 PM UTC+1, G G wrote:
>
> /* read in integer */
> scanf( "%ld", &number );
> ch = getchar(); /* need to handle the return when pressed */
>
Try replacngthis with
scanf("%ld\n", &number);
whitespace matches whitespace. It's very easy to add trailing spaces to input.
(You could just as well use scanf("%ld ", &number), but the newline makes it
obvious what your intention is).
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-04-22 13:29 -0400 |
| Message-ID | <5537DA7C.5050806@verizon.net> |
| In reply to | #60753 |
On 04/22/2015 12:42 PM, G G wrote:
> I have another question: i'm using os x 10.3.3, and when i do a control-D
> the program does not quit. it enters an infinite loop, well, a loop, it seems
> as if it is infinite, of course i stop it, using Xcode stop execution button.
>
> shouldn't control-D or control-z halt the execution of the program no matter
> what's being read in? i have not disable the control-D as far as i know.
That's something for OS X to define, and I don't know anything about
that. However, there's some obvious problems with your code that iare
almost certainly related to that issue.
> while ( programStatus == CONTINUE )
> {
> /* prompt user to enter an integer */
> printf( "Enter an integer to determine if it is even or odd : " );
>
> /* read in integer */
> scanf( "%ld", &number );
> ch = getchar(); /* need to handle the return when pressed */
The value returned by scanf() would be 1 if the number is successfully
read, 0 if the input stream cannot be interpreted as an integer, and EOF
if an I/O error occurred or if end-of-file occurs. Your code doesn't
check for any of those possibilities.
Note: you can use feof(stdin) and ferror(stdin) to distinguish those
last two possibilities, if you care about the distinction.
>
> if ( even( number ) )
> printf( "\n%ld is even\n\n", number );
> else
> printf( "\n%ld is odd\n\n", number );
>
> ch = ' '; /* make sure ch does not contain the \n character */
>
> puts("another number, y for yes, n for no?");
>
>
> /* allow only y,Y,n or N to control program continuation or termination */
>
> while ( ( (ch = getchar()) != '\n') || (characterOK == NO) )
getchar() returns EOF if there's an end-of-file or an I/O error. Again,
feof(stdin) and ferror(stdin) can be used to distinguish those cases.
Again, your code does nothing to check for either of those possibilities.
Obscure note: in the extremely unlikely event that UCHAR_MAX > INT_MAX
(which would require that CHAR_BIT >= 16), then getchar() can also
return EOF as a result of an ordinary read of a byte of data containing
the value (unsigned char)EOF. On such a platform, you'll need to check
both feof(stdin) and ferror(stdin) before deciding whether or not an
error occurred.
> {
> char temp = ch; /* needed because of the return, '\n', character */
>
> switch( temp )
> {
> case 'y':
> case 'Y':
> programStatus = CONTINUE;
> characterOK = YES;
> break;
>
> case 'n':
> case 'N':
> programStatus = FINISHED;
> characterOK = YES;
> break;
>
> default:
> puts("another number, y for yes, n for no?");
> characterOK = NO;
> ch = getchar();
The same issue applies here.
> ch = ' ';
> break;
>
> } /* end switch( temp ) */
>
> } /* end while ( ( (ch = getchar() ... ) */
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.lists@bsb.me.uk> |
|---|---|
| Date | 2015-04-22 20:57 +0100 |
| Message-ID | <87egnc9brp.fsf@bsb.me.uk> |
| In reply to | #60753 |
G G <gdotone@gmail.com> writes: > I have another question: i'm using os x 10.3.3, and when i do a control-D > the program does not quit. it enters an infinite loop, well, a loop, it seems > as if it is infinite, of course i stop it, using Xcode stop execution button. > > shouldn't control-D or control-z halt the execution of the program no matter > what's being read in? All control-D does is to close the input stream so that the next input operation will fail (getchar and scanf will return EOF for example). It's up to you to spot that and stop your program. If you look at your code, you'll see that it never looks for this sort of result. There's also a technicality: ch should be declared to be int not char. EOF is a negative integer value guaranteed to be different from any actualy character value that getchar can legitimately return. You should therefore always put the result into an int rather than a char variable. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-04-22 16:12 -0400 |
| Message-ID | <5538009B.9090306@verizon.net> |
| In reply to | #60785 |
On 04/22/2015 03:57 PM, Ben Bacarisse wrote: ... > There's also a technicality: ch should be declared to be int not char. > EOF is a negative integer value ... Correct. > ... guaranteed to be different from any > actualy character value that getchar can legitimately return. Citation, please? I found no such guarantee in the definition of EOF (7.21.1p3) nor in the definition of getchar() (7.21.7.6). In the unlikely event that UCHAR_MAX > INT_MAX, getchar()'s definition combined with the reversibility requirements for I/O on binary streams (7.21.2p3) imply that getchar() must return EOF when reading a byte that was written by calling putchar(EOF).
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.lists@bsb.me.uk> |
|---|---|
| Date | 2015-04-22 23:14 +0100 |
| Message-ID | <87383rak09.fsf@bsb.me.uk> |
| In reply to | #60789 |
James Kuyper <jameskuyper@verizon.net> writes: > On 04/22/2015 03:57 PM, Ben Bacarisse wrote: > ... >> There's also a technicality: ch should be declared to be int not char. >> EOF is a negative integer value ... > > Correct. > >> ... guaranteed to be different from any >> actualy character value that getchar can legitimately return. > > Citation, please? I found no such guarantee in the definition of EOF > (7.21.1p3) nor in the definition of getchar() (7.21.7.6). Right. I forgot this was comp.lang.c and simplified matters for the OP. > In the unlikely event that UCHAR_MAX > INT_MAX, getchar()'s definition > combined with the reversibility requirements for I/O on binary streams > (7.21.2p3) imply that getchar() must return EOF when reading a byte that > was written by calling putchar(EOF). I am not sure this 100% right. The reversibility is phrased in terms of characters and I can't persuade myself that putchar(EOF) must write a character that will result in EOF being returned by getchar. Might such an implementation not use a character set smaller than the set of char values -- for example, masking off one or more bits? What do such implementations normally do, or aren't there any? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-04-22 18:56 -0400 |
| Message-ID | <55382705.7090007@verizon.net> |
| In reply to | #60810 |
On 04/22/2015 06:14 PM, Ben Bacarisse wrote: > James Kuyper <jameskuyper@verizon.net> writes: ... >> In the unlikely event that UCHAR_MAX > INT_MAX, getchar()'s definition >> combined with the reversibility requirements for I/O on binary streams >> (7.21.2p3) imply that getchar() must return EOF when reading a byte that >> was written by calling putchar(EOF). > > I am not sure this 100% right. The reversibility is phrased in terms of > characters and I can't persuade myself that putchar(EOF) must write a > character that will result in EOF being returned by getchar. Might such > an implementation not use a character set smaller than the set of char > values -- for example, masking off one or more bits? What do such > implementations normally do, or aren't there any? I've always assumed that 7.21.2p3 was using "character" with the meaning specified by 3.7.1: "〈C〉 bit representation that fits in a byte", or perhaps 3.7 itself: "〈abstract〉 member of a set of elements used for the organization, control, or representation of data." The definition of "multibyte character" refers to the extended character set, and the definition of "wide character" refers to the current locale, but neither the <abstract> nor the <C> definition of "character" itself are text-oriented; they refer only to bits, byte, and data. All C I/O, including binary I/O of non-character types by functions such as fwrite() and fread(), is ultimately defined in terms of the behavior of fputc() and fgetc() operating on the individual bytes of the representation of those object. I think it would therefore be inappropriate to interpret "character", as it is used in the definition of those functions, as restricted to those values of char type that are actually defined as representing text characters. Writing a double to a binary file with fwrite(), and reading it back again with fread(), would not be guaranteed to produce a result representing the same value, if fputc() or fgetc() were allowed to, as you suggest, mask off bits. That would break an awful lot of my code.
[toc] | [prev] | [next] | [standalone]
| From | G G <gdotone@gmail.com> |
|---|---|
| Date | 2015-04-23 07:59 -0700 |
| Message-ID | <4cc6a177-a075-46d2-a08c-ca695687471d@googlegroups.com> |
| In reply to | #60434 |
I think this maybe better???
values returned from getchar() are assigned to variable of type int.
scanf( "%ld", &number) is checked to see if it returns a number.
a while( ( c = getchar() ) !== '\n' ) is used to eat up, so to speak, the
return, newline, '\n' character.
uh, in the function moreNumber() it seems to me to be reasonable
to read in a character of type char, scanf( "%c", &choice);
but please let me know you guys a great. you'll make a C programmer
out of me yet. :-)
there is one thing though i did try using the scan("ld\n", &number) to handle
the return character but that didn't work on my system.
Thanks everyone,thanks for sticking with me, i'll get it :-)
g.
/*************************************************************************************/
/*
This program reads in an integer, checks to see if the integer is
even or odd and writes a message indicating whether the number
is even or odd.
The program ask "Are there more numbers y for yes, n for no?" base on
the user answer 'y','Y','N','n' the program will continue or stop.
*/
#include <stdio.h>
#define YES 1
#define NO 0
/* enumeration constants for continuing the program */
enum Status { FINISHED, CONTINUE };
/* function prototype */
int even( long int );
enum Status moreNumbers(void);
int main( void )
{
long int number;
int thisIsInteger;
int c;
enum Status programStatus = CONTINUE;
while ( programStatus == CONTINUE )
{
/* prompt user to enter an integer */
printf( "Enter an integer to determine if it is even or odd : " );
/* read in integer */
thisIsInteger = scanf( "%ld", &number );
while( (c = getchar()) != '\n' );
if ( thisIsInteger )
{
if ( even( number ) )
printf( "\n%ld is even\n\n", number );
else
printf( "\n%ld is odd\n\n", number );
// ckeck to see if there are more number
programStatus = moreNumbers();
} /* end if ( thisIsInteger ) */
} /* end while ( programStatus ... ) */
return 0;
} /* end main( ... ) */
/********** even( ... ) *****************/
int even( long int n )
{
if ( ( n % 2) == 0 ) /* return (n % 2)? 1: 0 */
return 1;
else
return 0;
} /* end even( ... ) */
/********** moreNumbers( ... ) **********/
enum Status moreNumbers(void)
{
char choice;
int c;
int enteredDataOk = NO;
enum Status status = FINISHED;
while( enteredDataOk == NO )
{
puts(" are there more numbers y for yes or n for no? ");
scanf("%c", &choice );
while( (c = getchar()) != '\n' );
switch ( choice )
{
case 'y' :
case 'Y' :
enteredDataOk = YES;
status = CONTINUE;
break;
case 'n' :
case 'N' :
enteredDataOk = YES;
status = FINISHED;
break;
default:
break;
} /* end switch ( choice) */
} /* while ( enteredDataOk ...) */
return status;
} /* end moreNumber( ... ) */
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web