[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

I think this is an impossible assignment...could you help?

Jack

8/30/2011 9:01:00 PM

Ok, here's the deal...my instructor wants us to do the following
program. Only one problem: what must I use to get this program to work
right? Do I use combinations of if, for and while statements, or just
if statements or what? I have tried nested if and while statements and
CANNOT get the program to execute properly... Perhaps an experienced
programmer(unlike myself) could give me a little insight on how to do
this problem...
ANY help would greatly be appreciated. If there's nething i can help
someone else with...i will...THANK YOU

COMSC 1613 Programming I (C) Programming Assignment
3

In this assignment, you will write a 'C' function that will approximate
the action of the command scanf("%d",&x); namely, to read ASCII
character
digits from the standard input stream and convert/interpret the sequence
into a binary integer.

Consider the following implementation of main.

#include
#define INVALID 0x80000000

long scan_int(void); /* the prototype */

int main(void)
{long num, i;
printf("\nenter an integer: ");
for(i=1; (num = scan_int()) != -999; printf("\n\n\nenter an integer: "))
{ if (num == INVALID)
printf("\n you entered an invalid sequence\n");
else
{
printf("\nthe %ld-th integer read was %ld\n", i, num);
++i;
}
}
return (0);

}

Use this main() as a driver. You write function
long scan_int(void);

The function scan_int will use getchar() to read one character at a time
from the standard input and from the digits read compute "on the fly"
the
integer value they represent. The function will return the integer
computed. If the data entered is not appropriate to be interpreted as
an
integer, the function will return INVALID as defined in the program.
White space will be used to mark the beginning and end of a number.

Do not use arrays/strings and do not use atoi() and do not use scanf()
or
fscanf() or any other library functions other than getchar(). Comment
your code thoroughly.

The following is an example execution of the program you will write:

Script command is started on Fri Aug 19 16:19:47 CDT 2011.
$ a.out

enter an integer: 457

the 1-th integer read was 457

enter an integer: -34

the 2-th integer read was -34

enter an integer: +1

the 3-th integer read was 1

enter an integer:

-967835

the 4-th integer read was -967835

enter an integer: 45h5

you entered an invalid sequence

enter an integer: ---56

you entered an invalid sequence

enter an integer: 45+9

you entered an invalid sequence

enter an integer: hello

you entered an invalid sequence

enter an integer: -

you entered an invalid sequence

enter an integer: +

you entered an invalid sequence

enter an integer: -999

$
66 Answers

Ian Collins

8/30/2011 9:18:00 PM

0

On 08/31/11 09:01 AM, Jack wrote:
> Ok, here's the deal...my instructor wants us to do the following
> program. Only one problem: what must I use to get this program to work
> right? Do I use combinations of if, for and while statements, or just
> if statements or what? I have tried nested if and while statements and
> CANNOT get the program to execute properly... Perhaps an experienced
> programmer(unlike myself) could give me a little insight on how to do
> this problem...
> ANY help would greatly be appreciated. If there's nething i can help
> someone else with...i will...THANK YOU
>
> COMSC 1613 Programming I (C) Programming Assignment
> 3
>
> In this assignment, you will write a 'C' function that will approximate
> the action of the command scanf("%d",&x); namely, to read ASCII
> character
> digits from the standard input stream and convert/interpret the sequence
> into a binary integer.
>
> Consider the following implementation of main.
>
> #include
> #define INVALID 0x80000000
>
> long scan_int(void); /* the prototype */
>
> int main(void)
> {long num, i;
> printf("\nenter an integer: ");
> for(i=1; (num = scan_int()) != -999; printf("\n\n\nenter an integer: "))
> { if (num == INVALID)
> printf("\n you entered an invalid sequence\n");
> else
> {
> printf("\nthe %ld-th integer read was %ld\n", i, num);
> ++i;
> }
> }
> return (0);

What awful style!

> }
>
> Use this main() as a driver. You write function
> long scan_int(void);

Start of with your own main, calling scan_int for progressively more
complex inputs, starting with one digit, then two or more then add a
sign until you get the complete funtion:

int main(void)
{
long result;

puts("enter 1");

assert( scan_int(void) == 1 );

// start with the return here until this passes.

puts("enter 11");

assert( scan_int(void) == 11 );

// then move it here and so on until all cases work.

puts("enter -1");

assert( scan_int(void) == -1 );

// add more tests here.

return 0;
}

--
Ian Collins

Jack

8/30/2011 9:20:00 PM

0


Ian --- you may have misudnerstood, the problem is to WRITE this scan_int
function! It is NOT given.

John Gordon

8/30/2011 9:29:00 PM

0

In <j3jj2t$eq3$1@speranza.aioe.org> Jack <spamtrap@trashcan.invalid> writes:

> Ok, here's the deal...my instructor wants us to do the following
> program. Only one problem: what must I use to get this program to work
> right? Do I use combinations of if, for and while statements, or just
> if statements or what? I have tried nested if and while statements and
> CANNOT get the program to execute properly... Perhaps an experienced
> programmer(unlike myself) could give me a little insight on how to do
> this problem...

A good start would be to show us what you wrote. Perhaps we can explain
where you went wrong.

--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

Jack

8/30/2011 9:44:00 PM

0

On Tue, 30 Aug 2011 21:29:25 +0000, John Gordon wrote:

> In <j3jj2t$eq3$1@speranza.aioe.org> Jack <spamtrap@trashcan.invalid>
> writes:
>
>> Ok, here's the deal...my instructor wants us to do the following
>> program. Only one problem: what must I use to get this program to
>> work right? Do I use combinations of if, for and while statements, or
>> just if statements or what? I have tried nested if and while
>> statements and CANNOT get the program to execute properly... Perhaps
>> an experienced programmer(unlike myself) could give me a little insight
>> on how to do this problem...
>
> A good start would be to show us what you wrote. Perhaps we can explain
> where you went wrong.

John --- Sure. Thought this forum was empty for a while, good to get a
reply at last. I'd like to fix this up by 4PM today!

here is the code I have already written...maybe you could
expand to it a little?

long scan_int(void)
{
int c ; /* character, nb type is int not char to allow EOF */
int sign='+'; /* + for positive number, - for negative */
long sum=0; /* stores sum */

while((c=getchar())==' '); /* whitespace delimeters */

if(c=='-') /* negative */
{sign='-';
c=getchar();
while((c=getchar())==' ');
if(c<'0'||c>'9')
return(INVALID);}

else if(c=='+') /* positive */
{sign='+';
c=getchar();
while((c=getchar())==' ');
if(c<'0'||c>'9')
return(INVALID);}

if(c<'0'||c>'9')
{while(c!=' ') /* space delimeter */
c=getchar();
return(INVALID);}

if(c=='-'||c=='+')
return INVALID;

if(c>='0'&&c<='9')
{while(c>='0'&&c<='9')
{sum=sum*10+(c-48); /* update sum */
c=getchar();}
}

else return(INVALID);

if(sign=='-')
sum=sum*(-1);
return(sum);}

John Gordon

8/30/2011 10:16:00 PM

0

In <j3jli2$lp0$1@speranza.aioe.org> Jack <spamtrap@trashcan.invalid> writes:

> John --- Sure. Thought this forum was empty for a while, good to get a
> reply at last. I'd like to fix this up by 4PM today!

> here is the code I have already written...maybe you could
> expand to it a little?

Unfortunately I don't really have the time to make detailed code comments.
But here's a general program flow that might help you:

1. Read and discard whitespace.
2a. If the next char is a minus sign, remember it so you can make the
final return value negative.
2b. Else if the next char is a plus sign, ignore it because we assume
numbers are positive anyway.
3. Read one or more digits, computing the value of sum as we go.
4. Read and discard whitespace.
5. Read and discard a carriage return. (I think you missed this in
your original effort.)
6. Return sum.

At each step in the process, you know what kind of input you're expecting,
and if you get bad input, return INVALID.

Good luck!

--
John Gordon A is for Amy, who fell down the stairs
gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

Ian Collins

8/30/2011 10:34:00 PM

0

On 08/31/11 09:20 AM, Jack wrote:

Context?

> Ian --- you may have misudnerstood, the problem is to WRITE this scan_int
> function! It is NOT given.

No, I didn't. I was suggesting how you should start to write the
function. Start with the most basic case and grow it from there.

This is a classic learning excise for test driven development!

--
Ian Collins

William Ahern

8/30/2011 11:26:00 PM

0

John Gordon <gordon@panix.com> wrote:
<snip>
> 5. Read and discard a carriage return. (I think you missed this in
> your original effort.)

s/carriage return/new-line/

If the OP is using a text-oriented stdio stream, presumably any carriage
return would be dropped or translated to new-line.

Keith Thompson

8/30/2011 11:37:00 PM

0

Jack <spamtrap@trashcan.invalid> writes:
> On Tue, 30 Aug 2011 21:29:25 +0000, John Gordon wrote:
>
>> In <j3jj2t$eq3$1@speranza.aioe.org> Jack <spamtrap@trashcan.invalid>
>> writes:
>>
>>> Ok, here's the deal...my instructor wants us to do the following
>>> program. Only one problem: what must I use to get this program to
>>> work right? Do I use combinations of if, for and while statements, or
>>> just if statements or what? I have tried nested if and while
>>> statements and CANNOT get the program to execute properly... Perhaps
>>> an experienced programmer(unlike myself) could give me a little insight
>>> on how to do this problem...
>>
>> A good start would be to show us what you wrote. Perhaps we can explain
>> where you went wrong.
>
> John --- Sure. Thought this forum was empty for a while, good to get a
> reply at last. I'd like to fix this up by 4PM today!
>
> here is the code I have already written...maybe you could
> expand to it a little?
>
> long scan_int(void)
> {
> int c ; /* character, nb type is int not char to allow EOF */
> int sign='+'; /* + for positive number, - for negative */
> long sum=0; /* stores sum */
>
> while((c=getchar())==' '); /* whitespace delimeters */
>
> if(c=='-') /* negative */
> {sign='-';
> c=getchar();
> while((c=getchar())==' ');
> if(c<'0'||c>'9')
> return(INVALID);}
>
> else if(c=='+') /* positive */
> {sign='+';
> c=getchar();
> while((c=getchar())==' ');
> if(c<'0'||c>'9')
> return(INVALID);}
>
> if(c<'0'||c>'9')
> {while(c!=' ') /* space delimeter */
> c=getchar();
> return(INVALID);}
>
> if(c=='-'||c=='+')
> return INVALID;
>
> if(c>='0'&&c<='9')
> {while(c>='0'&&c<='9')
> {sum=sum*10+(c-48); /* update sum */
> c=getchar();}
> }
>
> else return(INVALID);
>
> if(sign=='-')
> sum=sum*(-1);
> return(sum);}

I find your code layout difficult to read (though not much worse than
the code in your original post, which presumably was from the
assignment).

I've taken the liberty of reformatting it. I have made no semantically
significant changes. I filtered it with "indent -kr", then made a few
more cosmetic changes.

long scan_int(void)
{
int c; /* character, nb type is int not char to
allow EOF */
int sign = '+'; /* + for positive number, - for negative
*/
long sum = 0; /* stores sum */

while ((c = getchar()) == ' ') { /* whitespace delimiters */
/* nothing */
}

if (c == '-') { /* negative */
sign = '-';
c = getchar();
while ((c = getchar()) == ' ') {
/* nothing */
}
if (c < '0' || c > '9') {
return INVALID;
}
}

else if (c == '+') { /* positive */
sign = '+';
c = getchar();
while ((c = getchar()) == ' ') {
/* nothing */
}
if (c < '0' || c > '9') {
return INVALID;
}
}

if (c < '0' || c > '9') {
while (c != ' ') { /* space delimiter */
c = getchar();
}
return INVALID;
}

if (c == '-' || c == '+') {
return INVALID;
}

if (c >= '0' && c <= '9') {
while (c >= '0' && c <= '9') {
sum = sum * 10 + (c - 48); /* update sum */
c = getchar();
}
}

else {
return INVALID;
}

if (sign == '-') {
sum = sum * (-1);
}
return sum;
}

Some comments on the code itself:

Return statements do not require parentheses.

48 is the ASCII encoding for '0', but how is the reader expected to know
that? Just write '0'.

You have a lot of redundancy. For example, the blocks for c == '-' and
c == '+' could be combined.

In the "update sum" block, the "if" is unnecessary. A while loop will
not be executed (or, if you prefer, will iterate 0 times) if the
condition is initially false.

To negate a number, you can use the unary "-" operator; multiplication
by -1 is overkill.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Ben Bacarisse

8/30/2011 11:51:00 PM

0

Jack <spamtrap@trashcan.invalid> writes:

> On Tue, 30 Aug 2011 21:29:25 +0000, John Gordon wrote:
>
>> In <j3jj2t$eq3$1@speranza.aioe.org> Jack <spamtrap@trashcan.invalid>
>> writes:
>>
>>> Ok, here's the deal...my instructor wants us to do the following
>>> program. Only one problem: what must I use to get this program to
>>> work right? Do I use combinations of if, for and while statements, or
>>> just if statements or what? I have tried nested if and while
>>> statements and CANNOT get the program to execute properly... Perhaps
>>> an experienced programmer(unlike myself) could give me a little insight
>>> on how to do this problem...
>>
>> A good start would be to show us what you wrote. Perhaps we can explain
>> where you went wrong.
>
> John --- Sure. Thought this forum was empty for a while, good to get a
> reply at last. I'd like to fix this up by 4PM today!

A reply was posted with in half an hour. That's about as good as you
can expect from Usenet (you may be reading this as a web forum but it is
really a Usenet news group).

> here is the code I have already written...maybe you could
> expand to it a little?
>
> long scan_int(void)
> {
> int c ; /* character, nb type is int not char to allow EOF */
> int sign='+'; /* + for positive number, - for negative */
> long sum=0; /* stores sum */
>
> while((c=getchar())==' '); /* whitespace delimeters */

So far so good but do you really find that easy to read? I'd write it
like this:

long scan_int(void)
{
int c; /* character, nb type is int not char to allow EOF */
int sign = '+'; /* + for positive number, - for negative */
long sum = 0; /* stores sum */

while ((c = getchar()) == ' '); /* whitespace delimeters */

Note the indentation and extra spaces. They get even more significant
later.

On a more important note, ' ' is not the only white space. Look up the
function in the header ctype.h (isspace, etc.) or, if you think you
should not use these yet, write a more complex test.

> if(c=='-') /* negative */
> {sign='-';
> c=getchar();
> while((c=getchar())==' ');
> if(c<'0'||c>'9')
> return(INVALID);}
>
> else if(c=='+') /* positive */
> {sign='+';
> c=getchar();
> while((c=getchar())==' ');
> if(c<'0'||c>'9')
> return(INVALID);}

I find this very hard to read all jammed-up like that. Do you really
want to accept input like this: " + 99"? scanf's %d format does not
so I suspect you should not do so either.

> if(c<'0'||c>'9')
> {while(c!=' ') /* space delimeter */
> c=getchar();

Are you sure this loop will end? Here's a tip: every time you write a
loop ask if will always end. If you think it will try to prove yourself
*wrong*. If you can't find any way to make the loop go on forever, you
may be safe!

> return(INVALID);}

In general, input functions should not read stuff that they don't
understand. If there is non-numeric data you should probably leave it
alone. Unfortunately you are hampered by a terrible specification. If
you do as you are told (emulate scanf and use the given driver) you can
not test non-numeric input because it will be left unread.

> if(c=='-'||c=='+')
> return INVALID;
>
> if(c>='0'&&c<='9')
> {while(c>='0'&&c<='9')
> {sum=sum*10+(c-48); /* update sum */

48? Hint: what does this do: printf("%d\n", '0'); ?

> c=getchar();}
> }
>
> else return(INVALID);

You are very nearly home and dry.

Once you've tidied it up, I think you will find that you can remove a
few of the invalid return tests. It's tempting to return an error as
soon as you know something is wrong, but the code is often easier to
follow if you have fewer tests and later ones will often catch earlier
errors.

> if(sign=='-')
> sum=sum*(-1);
> return(sum);}

You can set sign to anything you like as soon as you see the + or the -
in the input. Given that freedom, can you think of something to set it
to that would simplify this last bit if code?

I've likely missed some tings because the code is all crushed up and not
easy for me to read, but it looks pretty close to done.

--
Ben.

Ian Collins

8/30/2011 11:59:00 PM

0

On 08/31/11 09:43 AM, Jack wrote:
> On Tue, 30 Aug 2011 21:29:25 +0000, John Gordon wrote:
>
>> In<j3jj2t$eq3$1@speranza.aioe.org> Jack<spamtrap@trashcan.invalid>
>> writes:
>>
>>> Ok, here's the deal...my instructor wants us to do the following
>>> program. Only one problem: what must I use to get this program to
>>> work right? Do I use combinations of if, for and while statements, or
>>> just if statements or what? I have tried nested if and while
>>> statements and CANNOT get the program to execute properly... Perhaps
>>> an experienced programmer(unlike myself) could give me a little insight
>>> on how to do this problem...
>>
>> A good start would be to show us what you wrote. Perhaps we can explain
>> where you went wrong.
>
> John --- Sure. Thought this forum was empty for a while, good to get a
> reply at last. I'd like to fix this up by 4PM today!
>
> here is the code I have already written...maybe you could
> expand to it a little?
>
> long scan_int(void)
> {
> int c ; /* character, nb type is int not char to allow EOF */
> int sign='+'; /* + for positive number, - for negative */
> long sum=0; /* stores sum */

In addition to the other comments, most of those comments would be
considered excessive, especially the last one!

--
Ian Collins