Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > line of array from stdin

Reply
Thread Tools

line of array from stdin

 
 
Susan Sherpi
Guest
Posts: n/a
 
      10-19-2003
Hi. Thanks to Eric Sosman for showing me what was wrong with my code in an
earlier posting. He wrote, quoting me:

>> I want to read a line of decimal integers from standard input into an
>> array, stopping when a newline is encountered, and I'd like the
>> function to return the number of values read in.
>>
>> ----------------------------
>> int read_array(int p[])
>> {
>> j=0;
>> while(scanf("%d",&p[j])==1)
>> j++;
>> return j;
>> }
>> ----------------------------
>>
>> I thought that as soon as scanf found a character that wasn't a decimal
>> number, it wouldn't be able to put it in the array and would return 0,
>> and I'd bust out of the while loop - but that doesn't happen.

>
> As used here, scanf() skips white space -- and newlines
> are considered white space.



Ah yes that seems obvious now. I suppose I could just have the user end a
line of input with a random non-whitespace non-numeric character - would
make my life easier, but seems like a dumb solution.


> I'd suggest using two functions: read an entire single line with
> fgets(), and then use strtol() repeatedly to convert the numbers
> (and check for garbage).


Thanks. First I tried using sscanf on the output of fgets, but it just
kept reading the first number in the string, of course... I see strtol is
designed for this, great, but the documentation I have on strtol is so
terse, I'm afraid I can't figure out how to call it repeatedly. I
understand it reads as much of the string as it can convert into a number,
then returns a pointer to the beginning of the unused portion of the
string so the next call can start where the last one left off. Could some
kind soul show me an example of repeated calls to strtol? And can I have
strtol use both whitespace and commas as alternative field delimiters?

Susan



 
Reply With Quote
 
 
 
 
Malcolm
Guest
Posts: n/a
 
      10-19-2003

"Susan Sherpi" <(E-Mail Removed)> wrote in message
> I see strtol is designed for this, great, but the documentation I have on
> strtol is so terse, I'm afraid I can't figure out how to call it

repeatedly.

/*
read a line of integers from stdin.
Inputs ret - return pointer for integers read.
len - size of the buffer (for safety)
Returns: No integer read if successful, -1 on error
*/
int readint(int *ret, int len)
{
char buff[1024];
char *ptr;
char *tmp;
int answer = 0;

/* read a line, return -1 if error */
if( fgets(buff, 1024, stdin) == NULL)
return -1;

/* return -1 if fgets() didn't read the whole line */
if(!strchr(buff, '\n'))
return -1;

ptr = buff;
/* skip leading whitespace */
while(isspace(*ptr))
ptr++;

/* do out loop until ptr points to the terminating NUL */
while(*ptr)
{
/* read an integer */
/* the pointer tmp holds the first non-digit strtol encountered */
ret[answer] = (int) strtol(ptr, &tmp, 10);
/* if tmp equals ptr we have garbage and not a number */
if(tmp == ptr)
return -1;
ptr = tmp;
answer++;
/* here's a bit for you to do. You need to check for whitespace and
commas, and skip ptr so it jumps over them */
/* you also want to check that answer isn't greater or equal to len */
}
/* return the number of integers we read */
return answer;
}


 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      10-20-2003
Susan Sherpi wrote:
>
> Hi. Thanks to Eric Sosman for showing me what was wrong with my
> code in an earlier posting. He wrote, quoting me:
>
> >> I want to read a line of decimal integers from standard input
> >> into an array, stopping when a newline is encountered, and
> >> I'd like the function to return the number of values read in.
> >>

.... snip ...
>
> > I'd suggest using two functions: read an entire single line with
> > fgets(), and then use strtol() repeatedly to convert the numbers
> > (and check for garbage).

>
> Thanks. First I tried using sscanf on the output of fgets, but it
> just kept reading the first number in the string, of course... I
> see strtol is designed for this, great, but the documentation I


To make sscanf advance, try the following. You can get the source
of ggets at:

<http://cbfalconer.home.att.net/download/>

#include <stdio.h>
#include <stdlib.h>
#include "ggets.h"

int countints(void)
{
char *ln;
int num;
int count;
int ix, delta;

count = 0; ix = 0;
if (0 == ggets(&ln)) {
while (1 == sscanf(&ln[ix], "%d%n", &num, &delta)) {
printf("[%d]%d ", ix, num);
ix += delta;
count++;
}
printf(": %d\n", count);
free(ln);
}
return count;
} /* countints */

/* ------------------ */

int main(void)
{
while (countints()) continue;
return 0;
} /* main */

You can easily gussy things up to store the values in an array.

--
Chuck F ((E-Mail Removed)) ((E-Mail Removed))
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      10-20-2003
Malcolm wrote:
>
> "Susan Sherpi" <(E-Mail Removed)> wrote in message
> > I see strtol is designed for this, great, but the documentation I have on
> > strtol is so terse, I'm afraid I can't figure out how to call it

> repeatedly.
>
> /*
> read a line of integers from stdin.
> Inputs ret - return pointer for integers read.
> len - size of the buffer (for safety)
> Returns: No integer read if successful, -1 on error
> */
> int readint(int *ret, int len)
> {
> char buff[1024];
> char *ptr;
> [...]
> ptr = buff;
> /* skip leading whitespace */
> while(isspace(*ptr))
> ptr++;
> [... and then apply strtol(ptr,...) ...]


There are two problems here: One outright error and one
inefficiency.

The error is that isspace() and friends take an `int'
argument whose value is either EOF (not an issue here) or
the value of an `unsigned char'. On a system where plain
`char' is signed, the conversion of `*ptr' to an `int'
can produce negative values, which are clearly not within
the range of an `unsigned char', and demons will fly out
of your nose. Write instead

while (isspace( (unsigned char)*ptr ))

The inefficiency is that strtol() skips leading white
space all by itself without external help; the loop is
altogether unnecessary! (I imagine it was inserted in
the sample code to satisfy a requirement laid down by
the Department of Redundancy Dept.)

--
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Susan Sherpi
Guest
Posts: n/a
 
      10-20-2003
CBFalconer <(E-Mail Removed)> wrote:
> Susan Sherpi wrote:
>>
>> Hi. Thanks to Eric Sosman for showing me what was wrong with my
>> code in an earlier posting. He wrote, quoting me:
>>
>> >> I want to read a line of decimal integers from standard input
>> >> into an array, stopping when a newline is encountered, and
>> >> I'd like the function to return the number of values read in.
>> >>

> ... snip ...
>>
>> > I'd suggest using two functions: read an entire single line with
>> > fgets(), and then use strtol() repeatedly to convert the numbers
>> > (and check for garbage).

>>
>> Thanks. First I tried using sscanf on the output of fgets, but it
>> just kept reading the first number in the string, of course... I
>> see strtol is designed for this, great, but the documentation I

>
> To make sscanf advance, try the following. You can get the source
> of ggets at:
>
> <http://cbfalconer.home.att.net/download/>
>
> #include <stdio.h>
> #include <stdlib.h>
> #include "ggets.h"
>
> int countints(void)
> {
> char *ln;
> int num;
> int count;
> int ix, delta;
>
> count = 0; ix = 0;
> if (0 == ggets(&ln)) {
> while (1 == sscanf(&ln[ix], "%d%n", &num, &delta)) {



Thanks --what is the %n format specifier? it's not on my list

Susan
 
Reply With Quote
 
Ed Morton
Guest
Posts: n/a
 
      10-20-2003


On 10/20/2003 11:18 AM, Susan Sherpi wrote:
> CBFalconer <(E-Mail Removed)> wrote:
>

<snip>
>> while (1 == sscanf(&ln[ix], "%d%n", &num, &delta)) {

>
>
>
> Thanks --what is the %n format specifier? it's not on my list


You can look it up on-line at:

http://www.acm.uiuc.edu/webmonkeys/b....12.html#scanf

Regards,

Ed.

> Susan


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
peek at stdin, flush stdin Johnathan Doe C Programming 5 05-17-2013 04:30 PM
How to pass stdin of a C++ program to the stdin of a process createdwith ShellExecute() Ben C Programming 2 08-29-2009 09:47 PM
STDIN, OUT, ERR and $stdin, out, err - Differences? Terry Cooper Ruby 7 06-09-2009 05:48 AM
Reading from stdin then launching a program that reads from stdin strange behaviour Stefano Sabatini Perl Misc 6 07-29-2007 10:38 PM
Reading stdin once confuses second stdin read Charlie Zender C Programming 6 06-21-2004 01:39 PM



Advertisments