This might be of help, as the subject was discussed frequently.

Best regards
Martin

/*
DESCRIPTION:
 my_sscanf without malloc. Its helpers and spinoffs:
 my_atoi
 my_atof
 my_strtol
 my_strtoul
 my_strtod

 No string, language or complete error support and other limitations.
  
 Based on glibc-1.09  by  Free Software Foundation, Inc.
 so this is GPL'ed.

 Adapted by  Martin Reczko ([EMAIL PROTECTED]), July 2001


SETTINGS:

 For now, just one language supported: The one with . as a decimal
point.
 Change as needed:
 #define DECIMALPOINT '.'

 To avoid call to pow, so no math lib is needed
 #define SLOW_POWER_CALCULATION

 For testing
 #define STANDALONE_TEST
 to include this in RTL code, #undef STANDALONE_TEST below

COMPILE:
 if SLOW_POWER_CALCULATION is defined:
  cc my_sscanf.c
 else
  cc my_sscanf.c -lm


TESTRUN:
./a.out
Enter format string for: one int, one float, one double (or quit):%x
must match  %f %lf
Enter string for one int and one float:123  must      match 1e-9
-3.2e123 

String:123  must      match 1e-9 -3.2e123 

Format:%x must match  %f %lf

Number of assigned arguments: 3
Values: int: 291 float: 1.000000e-09 double: -3.200000e+123
Enter format string for: one int, one float, one double (or quit):quit


GNU NOTICE from glibc:

Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */


/* #define DBG  */  /* very noisy debug info */

/* MR14072001: see note above */
#define DECIMALPOINT '.'

#define SLOW_POWER_CALCULATION /* to avoid call to pow */

#define STANDALONE_TEST


#include <stdarg.h>
#ifdef STANDALONE_TEST
 #include <stdio.h> /* printf's for testing */
#else
 #define EOF 0
#endif
#include <errno.h>
#include <float.h> /* float limits ...*/
#ifndef SLOW_POWER_CALCULATION
 #include <math.h> /* pow */
#endif
#include <limits.h>
#include <ctype.h> /* isdigit... */



#ifdef STANDALONE_TEST
/* put these into my_stdio.h */
/* from here */
#define DOUBLE double 
int my_atoi(char *s);
DOUBLE my_atof(char *s);
long int my_strtol(const char *nptr, char **endptr, int base);
unsigned long int my_strtoul(const char *nptr, char **endptr, int base);
DOUBLE my_strtod(char *nptr,char **endptr);
int my_sscanf(char *s,char *format,...);

/* and #define sscanf my_sscanf  etc. if unmodified calls are needed */
/* to here */
#endif

#define wchar_t char

#define inchar()        ((c = *(mys++)) == 0 ? 0 : (++read_in, c))
#define conv_error()    return ((c == 0 || ungetc(c, s)), done)
#define input_error()   return (done == 0 ? -1 : done)
#define memory_error()  return ((errno = ENOMEM), -1)
#define is_longlong     is_long_double

int my_sscanf(char *s,char *format,...)
{

  va_list arg;
  register char *f = format;
  register char *mys=s;
  register char fc;             /* Current character of the format.  */
  register size_t done = 0;     /* Assignments done.  */
  register size_t read_in = 0;  /* Chars read in.  */
  register int c;               /* Last char read.  */
  register int do_assign;       /* Whether to do an assignment.  */
  register int width;           /* Maximum field width.  */

  /* Type modifiers.  */
  char is_short, is_long, is_long_double;
  int malloc_string;            /* Args are char ** to be filled in.  */
  /* Status for reading F-P nums.  */
  char got_dot, got_e;
  /* If a [...] is a [^...].  */
  char not_in;
  /* Base for integral numbers.  */
  int base;
  /* Signedness for integral numbers.  */
  int number_signed;
  /* Integral holding variables.  */
  long int num;
  unsigned long int unum;
  /* Floating-point holding variable.  */
  DOUBLE fp_num;

  /* Character-buffer pointer.  */
  register char *str, **strptr;
  size_t strsize;
  /* Workspace.  */
  char work[200];
  char *w;                      /* Pointer into WORK.  */

  /* MR14072001: see note above */
  wchar_t decimal=DECIMALPOINT;         /* Decimal point character.  */

#ifdef DBG
          printf("my_sscanf called with |%s| |%s|\n",s,format);
#endif

  va_start(arg, format);

  if ((s==NULL) || (format == NULL)) return -1;
  c = inchar();
  /* Run through the format string.  */
  while (*f != '\0')
    {
      fc = *f++;
      if (fc != '%')
        {
          /* Characters other than format specs must just match.  */
          if (c == EOF)
            input_error();
          if (isspace(fc))
            {
              /* Whitespace characters match any amount of whitespace.  */
              while (isspace (c))
                inchar ();
              continue;
            }
          else if (c == fc)
            (void) inchar();
          else
            return done;/*conv_error();*/
          continue;
        }
      /* Check for the assignment-suppressant.  */
      if (*f == '*')
        {
          do_assign = 0;
          ++f;
        }
      else
        do_assign = 1;
      /* Find the maximum field width.  */
      width = 0;
      while (isdigit(*f))
        {
          width *= 10;
          width += *f++ - '0';
        }
      if (width == 0)
        width = -1;

      /* Check for type modifiers.  */
      is_short = is_long = is_long_double = malloc_string = 0;
      while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a' || *f ==
'q')
        switch (*f++)
          {
          case 'h':
            /* int's are short int's.  */
            is_short = 1;
            break;
          case 'l':
            if (is_long)
              /* A double `l' is equivalent to an `L'.  */
              is_longlong = 1;
            else
              /* int's are long int's.  */
              is_long = 1;
            break;
          case 'q':
          case 'L':
            /* double's are long double's, and int's are long long int's.  */
            is_long_double = 1;
            break;
          case 'a':
            /* String conversions (%s, %[) take a `char **'
               arg and fill it in with a malloc'd pointer.  */
            malloc_string = 1;
            break;
          }

      /* End of the format string?  */
      if (*f == '\0')
        return done;/*conv_error();*/

      /* Find the conversion specifier.  */
      w = work;
      fc = *f++;
      if (fc != '[' && fc != 'c' && fc != 'n')
        /* Eat whitespace.  */
        while (isspace(c))
          (void) inchar();
      switch (fc)
        {
        case '%':       /* Must match a literal '%'.  */
          if (c != fc)
            return done;/*conv_error();*/
          break;

        case 'n':       /* Answer number of assignments done.  */
          if (do_assign)
            *va_arg(arg, int *) = read_in;
          break;

        case 'c':       /* Match characters.  */
          if (do_assign)
            {
              str = va_arg (arg, char *);
              if (str == NULL)
                return -1;/*conv_error ();*/
            }

          if (c == EOF)
            input_error();

          if (width == -1)
            width = 1;

          if (do_assign)
            {
              do
                *str++ = c;
              while (inchar() != EOF && --width > 0);
            }
          else
            while (inchar() != EOF && width > 0)
              --width;

          if (do_assign)
            ++done;

          break;
#if 0 /* case without malloc should be handled... */
        case 's':               /* Read a string.  */
#define STRING_ARG
          if (do_assign)
            {
              if (malloc_string)
                {
                  /* The string is to be stored in a malloc'd buffer.  */
                  strptr = va_arg (arg, char **);
                  if (strptr == NULL)
                    return done;/*conv_error ();*/
                  /* Allocate an initial buffer.  */
                  strsize = 100;
                  *strptr = str = malloc (strsize);
                }
              else
                str = va_arg (arg, char *);
              if (str == NULL)
                return done;/*conv_error ();*/
            }
          STRING_ARG;

          if (c == EOF)
            input_error ();

          do
            {
              if (isspace (c))
                break;
#define STRING_ADD_CHAR(c)
              if (do_assign
                {
                  *str++ = c;
                  if (malloc_string && str == *strptr + strsize)
                    {
                      /* Enlarge the buffer. */
                      str = realloc (*strptr, strsize * 2);
                      if (str == NULL)
                        {
                          /* Can't allocate that much.  Last-ditch effort.  */
                          str = realloc (*strptr, strsize + 1);
                          if (str == NULL)
                            {
                              /* We lose.  Oh well.
                                 Terminate the string and stop converting,
                                 so at least we don't swallow any input.  */
                              (*strptr)[strsize] = '\0';
                              ++done;
                              return done;/*conv_error ();*/
                            }
                          else
                            {
                              *strptr = str;
                              str += strsize;
                              ++strsize;
                            }
                        }
                      else
                        {
                          *strptr = str;
                          str += strsize;
                          strsize *= 2;
                        }
                    }
                }
              STRING_ADD_CHAR (c);
            } while (inchar () != EOF && (width <= 0 || --width > 0));

          if (do_assign)
            {
              *str = '\0';
              ++done;
            }
          break;
#endif
        case 'x':       /* Hexadecimal integer.  */
        case 'X':       /* Ditto.  */ 
          base = 16;
          number_signed = 0;
          goto number;

        case 'o':       /* Octal integer.  */
          base = 8;
          number_signed = 0;
          goto number;

        case 'u':       /* Unsigned decimal integer.  */
          base = 10;
          number_signed = 0;
          goto number;

        case 'd':       /* Signed decimal integer.  */
          base = 10;
          number_signed = 1;
          goto number;

        case 'i':       /* Generic number.  */
          base = 0;
          number_signed = 1;

        number:
          if (c == EOF)
            input_error();

          /* Check for a sign.  */
          if (c == '-' || c == '+')
            {
              *w++ = c;
              if (width > 0)
                --width;
              (void) inchar();
            }

          /* Look for a leading indication of base.  */
          if (c == '0')
            {
              if (width > 0)
                --width;
              *w++ = '0';

              (void) inchar();

              if (tolower(c) == 'x')
                {
                  if (base == 0)
                    base = 16;
                  if (base == 16)
                    {
                      if (width > 0)
                        --width;
                      (void) inchar();
                    }
                }
              else if (base == 0)
                base = 8;
            }

          if (base == 0)
            base = 10;

          /* Read the number into WORK.  */
          do
            {
              if (base == 16 ? !isxdigit(c) :
                  (!isdigit(c) || c - '0' >= base))
                break;
              *w++ = c;
              if (width > 0)
                --width;
            } while (inchar() != EOF && width != 0);

          if (w == work ||
              (w - work == 1 && (work[0] == '+' || work[0] == '-')))
            /* There was on number.  */
            return done;/*conv_error();*/

          /* Convert the number.  */
          *w = '\0';
          if (number_signed)
            num = my_strtol (work, &w, base);
          else
            unum = my_strtoul (work, &w, base);
          if (w == work)
            return done;/*conv_error ();*/
#ifdef DBG
          printf("INTEGER part|%s| rest|%s| base:%d\n",work,w,base);
#endif
          if (do_assign)
            {
              if (! number_signed)
                {
                  if (is_longlong)
                    *va_arg (arg, unsigned  int *) = unum;
                  else if (is_long)
                    *va_arg (arg, unsigned long int *) = unum;
                  else if (is_short)
                    *va_arg (arg, unsigned short int *)
                      = (unsigned short int) unum;
                  else
                    *va_arg(arg, unsigned int *) = (unsigned int) unum;
                }
              else
                {
                  if (is_longlong)
                    *va_arg(arg, int *) = num;
                  else if (is_long)
                    *va_arg(arg, long int *) = num;
                  else if (is_short)
                    *va_arg(arg, short int *) = (short int) num;
                  else
                    *va_arg(arg, int *) = (int) num;
                }
              ++done;
#ifdef DBG
              printf("INTEGER arg# : %d assigned value: num:%d
umum:%d\n",done,num,unum);
#endif

            }
          break;

        case 'e':       /* Floating-point numbers.  */
        case 'E':
        case 'f':
        case 'g':
        case 'G':
          if (c == EOF)
            input_error();

          /* Check for a sign.  */
          if (c == '-' || c == '+')
            {
              *w++ = c;
              if (inchar() == EOF)
                /* EOF is only an input error before we read any chars.  */
                return done;/*conv_error();*/
              if (width > 0)
                --width;
            }

          got_dot = got_e = 0;
          do
            {
              if (isdigit(c))
                *w++ = c;
              else if (got_e && w[-1] == 'e' && (c == '-' || c == '+'))
                *w++ = c;
              else if (!got_e && tolower(c) == 'e')
                {
                  *w++ = 'e';
                  got_e = got_dot = 1;
                }
              else if (c == decimal && !got_dot)
                {
                  *w++ = c;
                  got_dot = 1;
                }
              else
                break;
              if (width > 0)
                --width;
            } while (inchar() != EOF && width != 0);

          if (w == work)
            return done;/*conv_error();*/
          if (w[-1] == '-' || w[-1] == '+' || w[-1] == 'e')
            return done;/*conv_error();*/

#ifndef MIB_HACKS
          /* Convert the number.  */
          *w = '\0';
          fp_num = my_strtod(work, &w);
#ifdef DBG
          printf("FLOAT part|%s| rest|%s| value:%e\n",work,w,fp_num);
#endif
          if (w == work)
            return done;/*conv_error();*/

          if (do_assign)
            {
              if (is_long_double)
                *va_arg(arg, double *) = fp_num;
              else if (is_long)
                *va_arg(arg, double *) = (double) fp_num;
              else
                *va_arg(arg, float *) = (float) fp_num;
              ++done;
#ifdef DBG
              printf("FLOAT arg# : %d assigned value: %e\n",done,fp_num);
#endif

            }
          break;
#endif /* MIB_HACKS */

#if 0
        case '[':       /* Character class.  */
          STRING_ARG;

          if (c == EOF)
            input_error();

          if (*f == '^')
            {
              ++f;
              not_in = 1;
            }
          else
            not_in = 0;

          while ((fc = *f++) != '\0' && fc != ']')
            {
              if (fc == '-' && *f != '\0' && *f != ']' &&
                  w > work && w[-1] <= *f)
                /* Add all characters from the one before the '-'
                   up to (but not including) the next format char.  */
                for (fc = w[-1] + 1; fc < *f; ++fc)
                  *w++ = fc;
              else
                /* Add the character to the list.  */
                *w++ = fc;
            }
          if (fc == '\0')
            return done;/*conv_error();*/

          *w = '\0';
          unum = read_in;
          do
            {
              if ((strchr (work, c) == NULL) != not_in)
                break;
              STRING_ADD_CHAR (c);
              if (width > 0)
                --width;
            } while (inchar () != EOF && width != 0);
          if (read_in == unum)
            return done;/*conv_error ();*/

          if (do_assign)
            {
              *str = '\0';
              ++done;
            }
          break;
#endif
        case 'p':       /* Generic pointer.  */
          base = 16;
          /* A PTR must be the same size as a `long int'.  */
          is_long = 1;
          goto number;
        }
    }

  return done;/*conv_error();*/
}

int my_atoi(char *s) {
   char *r;
   return my_strtol(s,&r,0);
}

DOUBLE my_atof(char *s) {
   char *r;
   return my_strtod(s,&r);
}   


/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
   If BASE is 0 the base is determined by the presence of a leading
   zero, indicating octal or a leading "0x" or "0X", indicating
hexadecimal.
   If BASE is < 2 or > 36, it is reset to 10.
   If ENDPTR is not NULL, a pointer to the character after the last
   one converted is stored in *ENDPTR.  */
#undef UNSIGNED
#if     UNSIGNED
unsigned long int
#define my_strtol       my_strtoul
#else
long int
#endif
my_strtol (const char *nptr,char **endptr,int base)
{
  int negative;
  register unsigned long int cutoff;
  register unsigned int cutlim;
  register unsigned long int i;
  register const char *s;
  register unsigned char c;
  const char *save;
  int overflow;

#ifdef DBG
  printf("my_strtol: string |%s| base: %d \n",nptr,base);
#endif

  if (base < 0 || base == 1 || base > 36)
    base = 10;

  s = nptr;

  /* Skip white space.  */
  while (isspace (*s))
    ++s;
  if (*s == '\0')
    goto noconv;

  /* Check for a sign.  */
  if (*s == '-')
    {
      negative = 1;
      ++s;
    }
  else if (*s == '+')
    {
      negative = 0;
      ++s;
    }
  else
    negative = 0;

  if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
    s += 2;

  /* If BASE is zero, figure it out ourselves.  */
  if (base == 0)
    if (*s == '0')
      {
        if (toupper (s[1]) == 'X')
          {
            s += 2;
            base = 16;
          }
        else
          base = 8;
      }
    else
      base = 10;

  /* Save the pointer so we can check later if anything happened.  */
  save = s;

  cutoff = ULONG_MAX / (unsigned long int) base;
  cutlim = ULONG_MAX % (unsigned long int) base;

  overflow = 0;
  i = 0;
  for (c = *s; c != '\0'; c = *++s)
    {
      if (isdigit (c))
        c -= '0';
      else if (isalpha (c))
        c = toupper (c) - 'A' + 10;
      else
        break;
      if (c >= base)
        break;
      /* Check for overflow.  */
      if (i > cutoff || (i == cutoff && c > cutlim))
        overflow = 1;
      else
        {
          i *= (unsigned long int) base;
          i += c;
        }
    }

  /* Check if anything actually happened.  */
  if (s == save)
    goto noconv;

  /* Store in ENDPTR the address of one character
     past the last character we converted.  */
  if (endptr != NULL)
    *endptr = (char *) s;

#if     !UNSIGNED
  /* Check for a value that is within the range of
     `unsigned long int', but outside the range of `long int'.  */
  if (i > (negative ?
           -(unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
    overflow = 1;
#endif

  if (overflow)
    {
      errno = ERANGE;
#if     UNSIGNED
      return ULONG_MAX;
#else
      return negative ? LONG_MIN : LONG_MAX;
#endif
    }

  /* Return the result of the appropriate sign.  */
  return (negative ? -i : i);

noconv:
  /* There was no number to convert.  */
  if (endptr != NULL)
    *endptr = (char *) nptr;
  return 0L;
}

#define UNSIGNED 1
#if     UNSIGNED
unsigned long int
#define my_strtol       my_strtoul
#else
long int
#endif
my_strtol (const char *nptr,char **endptr,int base)
{
  int negative;
  register unsigned long int cutoff;
  register unsigned int cutlim;
  register unsigned long int i;
  register const char *s;
  register unsigned char c;
  const char *save;
  int overflow;

#ifdef DBG
  printf("my_strtoul: string |%s| base: %d \n",nptr,base);
#endif

  if (base < 0 || base == 1 || base > 36)
    base = 10;

  s = nptr;

  /* Skip white space.  */
  while (isspace (*s))
    ++s;
  if (*s == '\0')
    goto noconv;

  /* Check for a sign.  */
  if (*s == '-')
    {
      negative = 1;
      ++s;
    }
  else if (*s == '+')
    {
      negative = 0;
      ++s;
    }
  else
    negative = 0;

  if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
    s += 2;

  /* If BASE is zero, figure it out ourselves.  */
  if (base == 0)
    if (*s == '0')
      {
        if (toupper (s[1]) == 'X')
          {
            s += 2;
            base = 16;
          }
        else
          base = 8;
      }
    else
      base = 10;

  /* Save the pointer so we can check later if anything happened.  */
  save = s;

  cutoff = ULONG_MAX / (unsigned long int) base;
  cutlim = ULONG_MAX % (unsigned long int) base;

  overflow = 0;
  i = 0;
  for (c = *s; c != '\0'; c = *++s)
    {
      if (isdigit (c))
        c -= '0';
      else if (isalpha (c))
        c = toupper (c) - 'A' + 10;
      else
        break;
      if (c >= base)
        break;
      /* Check for overflow.  */
      if (i > cutoff || (i == cutoff && c > cutlim))
        overflow = 1;
      else
        {
          i *= (unsigned long int) base;
          i += c;
        }
    }

  /* Check if anything actually happened.  */
  if (s == save)
    goto noconv;

  /* Store in ENDPTR the address of one character
     past the last character we converted.  */
  if (endptr != NULL)
    *endptr = (char *) s;

#if     !UNSIGNED
  /* Check for a value that is within the range of
     `unsigned long int', but outside the range of `long int'.  */
  if (i > (negative ?
           -(unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
    overflow = 1;
#endif

  if (overflow)
    {
      errno = ERANGE;
#if     UNSIGNED
      return ULONG_MAX;
#else
      return negative ? LONG_MIN : LONG_MAX;
#endif
    }

  /* Return the result of the appropriate sign.  */
  return (negative ? -i : i);

noconv:
  /* There was no number to convert.  */
  if (endptr != NULL)
    *endptr = (char *) nptr;
  return 0L;
}


#ifdef SLOW_POWER_CALCULATION
DOUBLE my_pow(DOUBLE val,int exp) {
  int i;
  DOUBLE x=1.0;

  if (exp>0) {
    for (i=1;i<=exp;i++) x*=val;
  } else {
    if (exp<0) {
      for (i=1;i<=-exp;i++) x/=val;
    }
  }
#ifdef DBG
  printf("pow num:%f exponent:%d factor:%e\n",val,exp,x);
#endif
  return x;
}
#define pow my_pow
#endif


/* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
   character after the last one used in the number is put in *ENDPTR. 
*/
DOUBLE my_strtod(char *nptr,char **endptr)
{
  register char *s;
  short int sign;
  wchar_t decimal;      /* Decimal point character.  */

  /* The number so far.  */
  DOUBLE num;
  DOUBLE exp;
  int got_dot;          /* Found a decimal point.  */
  int got_digit;        /* Seen any digits.  */

  /* The exponent of the number.  */
  long int exponent;

#ifdef DBG
          printf("strtod called with |%s|\n",nptr);
#endif

  if (nptr == NULL)
    {
      errno = EINVAL;
      goto noconv;
    }

  /* Figure out the decimal point character.  */
  /* if (mbtowc(&decimal, _numeric_info->decimal_point, 1) <= 0)
     decimal = (wchar_t) *_numeric_info->decimal_point;
  */
  /* MR14072001: see note above */
  decimal=DECIMALPOINT;

  s = nptr;

  /* Eat whitespace.  */
  while (isspace(*s))
    ++s;

  /* Get the sign.  */
  sign = *s == '-' ? -1 : 1;
  if (*s == '-' || *s == '+')
    ++s;
#ifdef DBG
  printf("sign: %d\n",sign);
#endif

  num = 0.0;
  got_dot = 0;
  got_digit = 0;
  exponent = 0;
  for (;; ++s)
    {
      if (isdigit (*s))
        {
          got_digit = 1;
#if 1
          /* Make sure that multiplication by 10 will not overflow.  */
          if (num > DBL_MAX * 0.1) {
            /* The value of the digit doesn't matter, since we have already
               gotten as many digits as can be represented in a `double'.
               This doesn't necessarily mean the result will overflow.
               The exponent may reduce it to within range.

               We just need to record that there was another
               digit so that we can multiply by 10 later.  */
            ++exponent;
#ifdef DBG
          printf("++exponent:%d\n",exponent);
#endif
          }
          else
#endif
            num = (num * 10.0) + (*s - '0');
#ifdef DBG
          printf("char1:%c num:%f got_dot:%d
exponent:%d\n",*s,num,got_dot,exponent);
#endif
          /* Keep track of the number of digits after the decimal point.
             If we just divided by 10 here, we would lose precision.  */
          if (got_dot) {
            --exponent;
#ifdef DBG
          printf("--exponent:%d\n",exponent);
#endif
          }
        }
      else {
        if (!got_dot && (wchar_t) *s == decimal) {
          /* Record that we have found the decimal point.  */
          got_dot = 1;
        }
        else
          /* Any other character terminates the number.  */
          break;
      }
    }

  if (!got_digit)
    goto noconv;

  if (tolower(*s) == 'e')
    {
      /* Get the exponent specified after the `e' or `E'.  */
      int save = errno;
      char *end;
      long int exp;

      errno = 0;
      ++s;
      exp = my_strtol(s, &end, 10);
      if (errno == ERANGE)
        {
          /* The exponent overflowed a `long int'.  It is probably a safe
             assumption that an exponent that cannot be represented by
             a `long int' exceeds the limits of a `double'.  */
          if (endptr != NULL)
            *endptr = end;
          if (exp < 0)
            goto underflow;
          else
            goto overflow;
        }
      else if (end == s)
        /* There was no exponent.  Reset END to point to
           the 'e' or 'E', so *ENDPTR will be set there.  */
        end = (char *) s - 1;
      errno = save;
      s = end;
      exponent += exp;
    }

  if (endptr != NULL)
    *endptr = (char *) s;

  if (num == 0.0)
    return 0.0;

  /* Multiply NUM by 10 to the EXPONENT power,
     checking for overflow and underflow.  */
  exp=pow(10.0, exponent);
#ifdef DBG
  printf("num:%f exponent:%d factor:%e\n",num,exponent,exp);
#endif

  if (exponent < 0)
    {
      if (num < DBL_MIN * exp)
        goto underflow;
    }
  else if (exponent > 0)
    {
      if (num > DBL_MAX * exp)
        goto overflow;
    }

  num *= exp;
#ifdef DBG
  printf("ret num:%e \n",num);
#endif

  return num * sign;

 overflow:
  /* Return an overflow error.  */
  errno = ERANGE;
  /*MR14072001  return HUGE_VAL * sign; *//* where is HUGE_VAL? */
  return DBL_MAX * sign;

 underflow:
  /* Return an underflow error.  */
  if (endptr != NULL)
    *endptr = (char *) nptr;
  errno = ERANGE;
  return 0.0;

 noconv:
  /* There was no number.  */
  if (endptr != NULL)
    *endptr = (char *) nptr;
  return 0.0;
}


#ifdef STANDALONE_TEST
main() {
  char f[255];
  char b[255];

  int ix;
  float fx;
  DOUBLE dx;
  int assigned;


  while (1) {
    printf("Enter format string for: one int, one float, one double (or
quit):");
    fgets(f,255,stdin);
    if ((f[0]=='q')&&(f[1]=='u')&&(f[2]=='i')&&(f[3]=='t')) break;
    printf("Enter string for one int and one float:");
    fgets(b,255,stdin);
    assigned=my_sscanf(b,f,&ix,&fx,&dx);
    printf("\nString:%s\nFormat:%s\nNumber of assigned arguments:
%d\nValues: int: %d float: %e double: %e\n\n",b,f,assigned,ix,fx,dx);
  }
}
#endif /* STANDALONE_TEST */

----- End of forwarded message from [EMAIL PROTECTED] -----
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
--
For more information on Real-Time Linux see:
http://www.rtlinux.org/

Reply via email to