edited by
864 views
0 votes
0 votes

"Pointer arguments enable a function to access and change objects in the function that called it. As an example, consider a function getint that performs free-format
input conversion by breaking a stream of characters into integer values, one integer per call. getint has to return the value it found and also signal end of file when there
is no more input. These values have to be passed back by separate paths, for no matter what value is used for EOF, that could also be the value of an input integer.
"

One solution is to have getint return the end of file status as its function value, while using a pointer argument to store the converted integer back in the calling
function. This is the scheme used by scanf as well; see Section 7.4.
The following loop fills an array with integers by calls to getint:
int n, array[SIZE], getint(int *);
for (n = 0; n < SIZE && getint(&array[n]) != EOF; n++)

Each call sets array[n] to the next integer found in the input and increments n. Notice that it is essential to pass the address of array[n] to getint. Otherwise there
is no way for getint to communicate the converted integer back to the caller.
Our version of getint returns EOF for end of file, zero if the next input is not a number, and a positive value if the input contains a valid number.
#include <ctype.h>
int getch(void);
void ungetch(int);
/* getint: get next integer from input into *pn */
int getint(int *pn)
{
int c, sign;
while (isspace(c = getch())) /* skip white space */
;
if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
ungetch(c); /* it is not a number */
return 0;
}
sign = (c == '-') ? -1 : 1;
if (c == '+' || c == '-')
c = getch();
for (*pn = 0; isdigit(c), c = getch())
*pn = 10 * *pn + (c - '0');
*pn *= sign;
if (c != EOF)
ungetch(c);
return c;
}

can any one explain i didn't get it .

this is a portion Chapter 5 - Pointers and Arrays 

edited by

1 Answer

2 votes
2 votes

Well, the function getint() has to return two things:

(i) A status of whether it has successfully read the number

(ii) The value of the number.

Now in C, a function can only return one value and by convention, the status is returned by the function and the caller passes a pointer for storing the value. EOF is convenient to use as a status code here since that resembles "end of file/input". Note that it's just a convention, it's NOT fundamentally required to return EOF for invalid or end of input, you could as well return any other value, however by convention EOF is used similar to other input functions like scanf.

Since we also need to store the actual value, the caller passes pointer (int *pn), where it would be stored. Think of it as an OUT parameter.

Coming to the function itself getint(), it is equivalent to scanf "%d" ie, it reads an integer from input stream.

while (isspace(c = getch())) /* skip white space */ 
  ;

This will skip all  leading white-spaces from input, ie, it will allow '   123',  to be parsed as number 123.

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

This allows to take sign of the integer: '+' or '-' and stores it in the sign variable.

if (c == '+' || c == '-') 
c = getch();

If there was a sign then we need to fetch the next character. However if there wasnt one in the first place, we already have the next character.

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

This is a typical for-loop for converting sequence of digits into integer, similar to atoi(). isdigit(c) tests if the char is digit, ie, between '0' - '9' and if it is, include it as part of the integer and fetch next digit. The "fetch next digit" part is c = getch().

*pn *= sign; 

After the function is done with reading digits, we have the integer. Now we multiply it by the sign. Note that sign is -1 if we had earlier encountered '-', so multiplying by sign we end up with negative integer.

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

Ok, this part is a bit tricky -;) The function uses getch() and ungetch() which are built on top of standard getc() function and use an internal buffer. The rationale is when we are reading digits we can only "stop" reading when the character is not a digit. However now we have read an extra character that is not really a part of the digit, so we need to again "unread" it, so that the next call of getch() will properly get that character.

For example - "123yz"

The for loop will read '1', '2', '3' and 'y'.  Reading '1', '2', '3' is fine since that forms a part of the number, however we also end up reading 'y', which terminates the for loop. But this character is not a digit, so we need to again "unread" it. A call to ungetch() would put 'y' back on the input buffer, so the next call to getch() would return 'y' and not 'z'. Basically getch() pops the character off the buffer and ungetch() pushes the character on the buffer. Please review the 4th chapter's postfix calculator, where they explain this concept.

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

This is a trivial loop, where 'n' elements are being inputted in the array.

Hope this helps -:) 

Related questions

0 votes
0 votes
0 answers
2