473,320 Members | 1,744 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

K&R 5-1

mdh
Hi All,
May I ask this. The exercise 5-1 asks one to correct an input in which
a non-digit follows a + or - . T & G show this:

/****/
if ( c == '+' || c == '-'){
d=c;

if ( !isdigit(c=getch())){

if (c !=EOF)
ungetch(c);

ungetch(d);

return d;

}
}
My question is: Does this not lead to an endless loop? (That's what I
seem to get) Or is this just illustrating something?

Complete code below.

Thanks in advance.

/****/
#include <stdio.h>
# include <ctype.h>
# define SIZE 10

int main () {

int getint ( int *);
int p, i, arr[SIZE];

for (p=0; getint( &arr[p]) != EOF; p++);

for ( i=0; i< SIZE; i++)
printf( "Converted input in Array idx(%d) = %d\n", i, arr[i]);

return 0;
}

/*******/

int getch(void);
void ungetch(int);

int getint(int *px){

int c, d, sign;

while ( isspace( c= getch())) ;

if ( ! isdigit (c) && c != '+' && c != '-' && c != EOF) {

ungetch(c);
return 0;
}

sign = (c=='-') ? -1:1;

if ( c == '+' || c == '-'){
d=c;

if ( !isdigit(c=getch())){

if (c !=EOF)
ungetch(c);

ungetch(d);

return d;

}
}
for (*px=0; isdigit(c); c=getch())
*px=*px * 10 + (c - '0');

*px=*px * sign;

if ( c != EOF)
ungetch(c);

return c;

}
/*********/

#define BUFSIZE 10


char buf[BUFSIZE];
int bufp=0;
int getch(void){

return (bufp 0) ? buf[--bufp]: getchar();

}
void ungetch(int c){

if ( bufp < BUFSIZE)

buf[bufp++] = c;

else

printf("Error: ungetch...buffer overflow");

}

Feb 3 '07 #1
9 1722
mdh wrote:
Hi All,
May I ask this. The exercise 5-1 asks one to correct an input in which
a non-digit follows a + or - . T & G show this:
The standard doesn't guarantee a pushback of more than one character
at a time. The solution presented is inherently non-portable. All you
can do is pushback the non-digit character, or the sign character, not
both. Some C libraries do allow multiple character pushbacks, but if
you really need such features, it may be better to wrap your own I/O
functions.

Feb 3 '07 #2
mdh
On Feb 3, 12:04 pm, "santosh" <santosh....@gmail.comwrote:
The standard doesn't guarantee a pushback of more than one character
at a time....

Thanks...good, I thought I was missing something.

Feb 3 '07 #3
santosh wrote, On 03/02/07 20:04:
mdh wrote:
>Hi All,
May I ask this. The exercise 5-1 asks one to correct an input in which
a non-digit follows a + or - . T & G show this:

The standard doesn't guarantee a pushback of more than one character
at a time.
If I recall correctly the program used a function called ungetch which
it defined, not the standard function ungetc, so your points from here
on are irrelevant to what the OP posted. Unfortunately, as you snipped
the parts of the code you are commenting on I have to rely on memory,
and my memory is poor, so I could be wrong. Snipping is good, but you
snipped too much on this occasion in my opinion.
The solution presented is inherently non-portable. All you
can do is pushback the non-digit character, or the sign character, not
both. Some C libraries do allow multiple character pushbacks, but if
you really need such features, it may be better to wrap your own I/O
functions.
Which, I believe, is what the solution the OP posted did. It was
probably doing it because IIRC the ungetch function was developed in one
of the earlier exercises in K&R.
--
Flash Gordon
Feb 3 '07 #4
mdh
On Feb 3, 1:36 pm, Flash Gordon <s...@flash-gordon.me.ukwrote:

If I recall correctly the program used a function called ungetch....
correct...it was developed as has been used quite extensively up to
now. The way it is written, there does not seem to be a limit on the
number of characters pushed back, and in fact, Tondo & G push back 2
characters in their answer. I just wanted to get a feel for why I was
entering an endless loop.

Full code below....( You mean not everyone uses google? :-) )

/****/

#include <stdio.h>
# include <ctype.h>
# define SIZE 10

int main () {

int getint ( int *);

int p, i, arr[SIZE];

for (p=0; getint( &arr[p]) != EOF; p++);

for ( i=0; i< SIZE; i++)
printf( "Converted input in Array idx(%d) = %d\n", i, arr[i]);

return 0;

}

/*******/
int getch(void);
void ungetch(int);

int getint(int *px){

int c, d, sign;

while ( isspace( c= getch())) ;

if ( ! isdigit (c) && c != '+' && c != '-' && c != EOF) {

ungetch(c);
return 0;

}

sign = (c=='-') ? -1:1;
if ( c == '+' || c == '-'){
d=c;

if ( !isdigit(c=getch())){

if (c !=EOF)
ungetch(c);

ungetch(d);

return d;

}

}

for (*px=0; isdigit(c); c=getch())
*px=*px * 10 + (c - '0');
*px=*px * sign;

if ( c != EOF)
ungetch(c);

return c;

}

/*********/
#define BUFSIZE 10

char buf[BUFSIZE];
int bufp=0;

int getch(void){

return (bufp 0) ? buf[--bufp]: getchar();

}

void ungetch(int c){
if ( bufp < BUFSIZE)

buf[bufp++] = c;

else

printf("Error: ungetch...buffer overflow");
}


Feb 3 '07 #5
santosh wrote:
mdh wrote:
>May I ask this. The exercise 5-1 asks one to correct an input
in which a non-digit follows a + or - . T & G show this:

The standard doesn't guarantee a pushback of more than one
character at a time. The solution presented is inherently
non-portable. All you can do is pushback the non-digit character,
or the sign character, not both. Some C libraries do allow
multiple character pushbacks, but if you really need such
features, it may be better to wrap your own I/O functions.
While there is nothing wrong with your post, an interesting fact
arises when you consider the actual mechanism used to implement
pushback. It turns out that many systems CAN push back multiple
chars, provided that the char following a '\n' is never accessed
[1]. This is very handy for such things as the OPs problem, or the
even worse "12.3e+x" [2] problem. A while back I published a short
test function to see what your system actually does.

[1] This is because access after the \n is what usually triggers
the refilling of the buffer. This in turn makes the (unwarranted)
assumption of buffered i/o.

[2] Note that none of these problem sequences involves the '\n'
character.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Feb 4 '07 #6
"mdh" <md**@comcast.netwrites:
On Feb 3, 1:36 pm, Flash Gordon <s...@flash-gordon.me.ukwrote:

>If I recall correctly the program used a function called ungetch....

correct...it was developed as has been used quite extensively up to
now. The way it is written, there does not seem to be a limit on the
number of characters pushed back, and in fact, Tondo & G push back 2
characters in their answer. I just wanted to get a feel for why I was
entering an endless loop.
See below.
Full code below....( You mean not everyone uses google? :-) )

/****/
Personally, I find separator comments like this visually distracting.
#include <stdio.h>
# include <ctype.h>
# define SIZE 10

int main () {

int getint ( int *);

int p, i, arr[SIZE];

for (p=0; getint( &arr[p]) != EOF; p++);
You can access outside the array unless you test that p < SIZE. Your
layout is all up the spout. I'd write it like this:

for (p = 0; p < SIZE && getint(&arr[p]) != EOF; p++) /* nothing */;

But this is also the source of your never-ending loop. When the input
is incorrect, getint does not return EOF but neither does it consume
any more input so you just keep going round and round.

I would suggest you change the interface so that getint returns true
(any non-zero integer) when it reads a number and false (0) when is
does not.
for ( i=0; i< SIZE; i++)
i < p would be better here since by now you know how many numbers your
have.
printf( "Converted input in Array idx(%d) = %d\n", i, arr[i]);

return 0;

}

/*******/
int getch(void);
void ungetch(int);

int getint(int *px){

int c, d, sign;

while ( isspace( c= getch())) ;

if ( ! isdigit (c) && c != '+' && c != '-' && c != EOF) {

ungetch(c);
return 0;

}

sign = (c=='-') ? -1:1;
if ( c == '+' || c == '-'){
d=c;

if ( !isdigit(c=getch())){

if (c !=EOF)
ungetch(c);

ungetch(d);

return d;
As I say, I would "return 0;" here. local variable d is then not needed.
>
}

}

for (*px=0; isdigit(c); c=getch())
*px=*px * 10 + (c - '0');
At the very least, indent the body of you loops!
*px=*px * sign;

if ( c != EOF)
ungetch(c);

return c;
and here I would return 0/1 depending on whether any digits were
actually consumed.
}

/*********/
#define BUFSIZE 10

char buf[BUFSIZE];
int bufp=0;

int getch(void){

return (bufp 0) ? buf[--bufp]: getchar();

}

void ungetch(int c){
if ( bufp < BUFSIZE)

buf[bufp++] = c;

else

printf("Error: ungetch...buffer overflow");
}
Since there is never much purpose in pushing back EOF, you could put
that test in the ungetch function and simplify getint a little bit.

--
Ben.
Feb 4 '07 #7
mdh
On Feb 4, 5:12 am, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
thanks for your input.

I also solved the endless loop problem by resetting the buffer to 0
when pushing back two characters...A little dirty as the integer
stored with this is undefined ( I have begun to like that word). :-)
Feb 5 '07 #8
On 3 Feb 2007 15:49:13 -0800, "mdh" <md**@comcast.netwrote:
>>
If I recall correctly the program used a function called ungetch....
correct...it was developed and has been used quite extensively up to
now. The way it is written, there does not seem to be a limit on the
number of characters pushed back ...
The limit is given by BUFSIZE.
F.

--

E-mail: info<at>simple-line<Punkt>de
Mar 16 '07 #9
On 4 Feb 2007 19:06:53 -0800, "mdh" <md**@comcast.netwrote:
>>
I would "return 0;" here.
Yes. I think that's a reasonable solution!
>
A little dirty as the integer stored with this is "undefined"...
Well, no problem. Since the function returns a 0 the caller is warned that
no input value has been (successfully) read.
My own solution:

/* Exercise 5-1 */

#include <stdio.h>
#include <ctype.h>

int getch(void);
void ungetch(int);

/* getint: get next integer from input into *pn */
int getint(int *pn)
{
int c, d, sign;

while (isspace(c = getch())) /* skip white space */
;
if (!isdigit(c) && c != EOF && c != '+' && c != '-')
{
ungetch(c); /* it's not a number */
return 0;
}
sign = (c == '-') ? -1 : 1;
if (c == '+' || c == '-')
{
d = c;
if (!isdigit(c = getch()))
{
if (c != EOF)
ungetch(c);
ungetch(d);
return 0;
}
}
for (*pn = 0; isdigit(c); c = getch())
*pn = 10 * *pn + (c - '0');
*pn *= sign;
if (c != EOF)
ungetch(c);

return c;
}

#define BUFSIZE 100

char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */

int getch(void) /* get a (possibly pushed-back) character */
{
return (bufp 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) /* push character back on input */
{
if (bufp >= BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++] = c;
}

#define SIZE 10

int main(void)
{
int i, n, c, array[SIZE], getint(int *);

for (n = 0; n < SIZE && (c = getint(&array[n])) != EOF && c != 0; n++)
;

for (i = 0; i < n; i++)
printf("array[%d] = %d\n", i, array[i]);

return 0;
}
F.

--

E-mail: info<at>simple-line<Punkt>de
Mar 16 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Collin VanDyck | last post by:
I have a basic understanding of this, so forgive me if I am overly simplistic in my explanation of my problem.. I am trying to get a Java/Xalan transform to pass through a numeric character...
1
by: DrTebi | last post by:
Hello, I have the following problem: I used to "encode" my email address within links, in order to avoid (most) email spiders. So I had a link like this: <a...
0
by: Thomas Scheffler | last post by:
Hi, I runned in trouble using XALAN for XSL-Transformation. The following snipplet show what I mean: <a href="http://blah.com/?test=test&amp;test2=test2">Test1&amp;</a> <a...
4
by: Luklrc | last post by:
Hi, I'm having to create a querysting with javascript. My problem is that javscript turns the "&" characher into "&amp;" when it gets used as a querystring in the url EG: ...
4
by: johkar | last post by:
When the output method is set to xml, even though I have CDATA around my JavaScript, the operaters of && and < are converted to XML character entities which causes errors in my JavaScript. I know...
8
by: Nathan Sokalski | last post by:
I add a JavaScript event handler to some of my Webcontrols using the Attributes.Add() method as follows: Dim jscode as String = "return (event.keyCode>=65&&event.keyCode<=90);"...
11
by: Jeremy | last post by:
How can one stop a browser from converting &amp; to & ? We have a textarea in our system wehre a user can type in some html code and have it saved to the database. When the data is retireved...
14
by: Arne | last post by:
A lot of Firefox users I know, says they have problems with validation where the ampersand sign has to be written as &amp; to be valid. I don't have Firefox my self and don't wont to install it only...
12
by: InvalidLastName | last post by:
We have been used XslTransform. .NET 1.1, for transform XML document, Dataset with xsl to HTML. Some of these html contents contain javascript and links. For example: // javascript if (a &gt; b)...
7
by: John Nagle | last post by:
I've been parsing existing HTML with BeautifulSoup, and occasionally hit content which has something like "Design & Advertising", that is, an "&" instead of an "&amp;". Is there some way I can get...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.