l i n u x - u s e r s - g r o u p - o f - d a v i s
Next Meeting:
July 7: Social gathering
Next Installfest:
Latest News:
Jun. 14: June LUGOD meeting cancelled
Page last updated:
2003 Apr 18 16:15

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
Re: [vox-tech] a better scanf?? (C-programming question)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [vox-tech] a better scanf?? (C-programming question)

Content-Type: multipart/mixed; boundary="t0UkRYy7tHLRMCai"
Content-Disposition: inline

Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Apr 18, 2003 at 04:48:50AM -0700, Andy Campbell wrote:
> >   Non-blocking with select/poll/busy-looping, reading into a
> > buffer, followed by sscanf when a return key is found will certainly
> > handle the second case... examples if that's what you want.
> I am trying to implement this but am unsuccessfull. Could you show me whe=
> some examples are?? Thank you!!


  Attached is a very simple command line interactive program... it's just
an example.  It does non-blocking IO with stdin, parses complete lines
when they are found with sscanf.  It accepts input from users or files (if=
stdin is redirected from a file).  This program uses standard cooked
input mode, so all the nice line editing keys (^W, backspace, ^U, ^C,
etc) work...

sample run:
msimons@salomon:~$ ./a.out=20
don't understand line: "blah"
set foo=3D123;
gotcha: store 123 into variable "foo"
set foo=3Dbar;
don't understand line: "set foo=3Dbar;"
set foo=3D123; junk
gotcha: store 123 into variable "foo"
garbage after command: " junk"
quitting soon

  In this code I set TIMEOUT high... because I have nothing to do
besides wait for use input, if you are doing some CPU bound stuff that
you want to check for user commands sometimes you would want to change
timeout to 0, and call this poll code once per major CPU loop...
  for user-interactiveness reasons, if you are doing CPU bound things=20
you should probably be using threads, one to watch for use input.

    Good Luck,

GPG key: http://simons-clan.com/~msimons/gpg/msimons.asc
Fingerprint: 524D A726 77CB 62C9 4D56  8109 E10C 249F B7FA ACBE

Content-Type: text/x-csrc; charset=us-ascii
Content-Disposition: attachment; filename="poll1.c"
Content-Transfer-Encoding: quoted-printable

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/poll.h>
#include <unistd.h>

/* size of user command buffer */
#define BUFFER_SIZE 4096

/* time to wait at poll call for data...=20
   FIXME: you may want 0 here,=20
especially if doing other things that don't use poll to trigger,
like calculations in the background... */
#define TIMEOUT 1000000

int main(void)
  int file =3D fileno(stdin);                         /* file number of std=
in */
  int result;                                      /* return code from poll=
  struct pollfd pd[] =3D { { file, POLLIN, 0 } };            /* data for po=
ll */

  char buffer[BUFFER_SIZE];                        /* buffer for user input=
  char *end =3D buffer;                         /* last position that is fu=
ll */

  int done =3D 0;                                         /* loop should st=
op */
  int error =3D 0;                                     /* some error happen=
ed */

  while (!done && !error)
  { /* looping time */
    if (((result =3D poll(pd, 1, TIMEOUT)) > 0))
    { /* have data to read */
      if (pd[0].revents =3D=3D POLLHUP)
        fprintf(stderr, "%s:%d %s warning: "
                "End of file reached with no 'quit' command\n",
          __FILE__, __LINE__, __FUNCTION__),
        error =3D 2;
      else if (pd[0].revents !=3D POLLIN)
        fprintf(stderr, "%s:%d %s warning: "
                "Unexpected poll result returned 0x%04X, "
                "expected one of 0x%04X\n",
          __FILE__, __LINE__, __FUNCTION__, pd[0].revents, pd[0].events),
        error =3D 2;
      { /* poll result expected, read some data */
        int size;

        if ((size =3D read(file, end, sizeof(buffer) - (end - buffer))) <=
=3D 0)
        { /* read failed some how */
          if ((size =3D=3D -1) && (errno !=3D EINTR))
            fprintf(stderr, "%s:%d %s error: "
                    "While reading, %d: %s\n",
              __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno)),
            error =3D 1;
          else if (size =3D=3D 0)
            fprintf(stderr, "%s:%d %s warning: "
                   "End of file reached with no 'quit' command\n",
              __FILE__, __LINE__, __FUNCTION__),
            error =3D 2;
          done =3D 1;
        { /* read is good, check for more commands */
          char *last;                   /* last character of this data line=
          char *offset =3D buffer;        /* first chracter of this data li=
ne */

          end +=3D size;                           /* increment stop positi=
on */
          while ((last =3D memchr(offset, '\n', end - offset)))
          { /* found a newline */
            int status =3D 0;
            int var;
            int start;
            int stop;
            *last =3D '\0';                            /* null terminate li=
ne */
            if ((sscanf(offset, "quit;%n", &status) =3D=3D 0) && status)
              printf("quitting soon\n"), done =3D 1;
            else if ((sscanf(offset, "set %n%*[^=3D]%n=3D%d;%n",=20
                     &start, &stop, &var, &status) =3D=3D 1) && status)
              printf("gotcha: store %d into variable \"%.*s\"\n",=20
                     var, stop - start, offset + start);

            if ((status) && (status !=3D (last - offset)))
            /* could use 'status' to check for more commands on this line */
              printf("garbage after command: \"%.*s\"\n",=20
                     last - offset - status, offset + status);
            else if (!status)
              printf("don't understand line: \"%.*s\"\n",=20
                     last - offset, offset);

            offset =3D last + 1;

          if (offset !=3D buffer)
            memcpy(buffer, offset, end - offset);
            end -=3D offset - buffer;
          else if (end =3D=3D (buffer + sizeof(buffer)))
            fprintf(stderr, "%s:%d %s error: "
                    "Comamnd line too long can't be more than %d bytes\n",
              __FILE__, __LINE__, __FUNCTION__, sizeof(buffer)),
            error =3D 2;

  return error;

#if 0
  if (fcntl(file, F_SETFL, O_NONBLOCK, 1))
  { /* setting non-blocking mode failed */
    fprintf(stderr, "%s:%d %s error: "
            "Failed to set non-blocking on stdin, %d: %s\n",
            __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno));
    return 1;


Content-Type: application/pgp-signature
Content-Disposition: inline

Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org


vox-tech mailing list

LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
Appahost Applications
For a significant contribution towards our projector, and a generous donation to allow us to continue meeting at the Davis Library.