Re: having problems with interactive error catching function

From: Al Bowers (xabowers_at_rapidsys.com)
Date: 01/01/04


Date: Thu, 01 Jan 2004 17:32:50 -0500


interpim wrote:
> ok the function is supposed to accept only non-negative integers... but it still accepts letters input through the function. Such as '23e' still passes through. I tried to use isalpha in the or statement to cause an error, but it causes an error for everything input. How do I make an error occur when anything other than numbers are put in?
>
> #include <stdio.h>
> #define MAXLINE 20
> int main(void)
> {
> char line[MAXLINE];
> int error,n;
> do{
> printf("Input a positive integer: ");
> fgets(line, MAXLINE, stdin);
> error=sscanf(line, "%d",&n) !=1||n<=0;
> if (error)
> printf("\nERROR: Do it again.\n");
> } while(error);
> }
>

Study up on the Standard C function strtoul. It is very
useful in validating a positive integer.

An example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

typedef enum {NO, YES} bool;

char *fgetline(FILE *fp);
char *getline(void);
bool StrtoUnsigned(const char *num, unsigned *ud);

int main(void)
{
    char *s;
    unsigned ud;

    while(1)
    {
       printf("Input a positive integer: ");
       fflush(stdout);
       s = getline();
       if(!s || StrtoUnsigned(s, &ud)) break;
       free(s);
       printf("\nERROR: Do it again.\n");
    }
    if(s)
    {
       printf("The number is %u\n",ud);
       free(s);
    }
    return 0;
}

bool StrtoUnsigned(const char *num, unsigned *ud)
{
    unsigned long ul;
    char *s;

    errno=0;
    ul = strtoul(num,&s,10);
    if(*num != '-' && *s == '\0' && errno != ERANGE &&
                       ul <= UINT_MAX)
    {
       *ud = ul;
       return YES;
    }
    return NO;
}

char *fgetline(FILE *fp)
{
    char *tmp,buf[63],*s,*s1;
    size_t count, size = 63;

    for(count = 1,tmp=s=NULL; (fgets(buf,sizeof buf,fp)!=NULL); )
    {
       if((tmp = realloc(s,count++*(size+1)))==NULL) break;
       if(s == NULL) *tmp='\0';
       s=tmp;
       strcat(s,buf);
       if((s1 = strrchr(s,'\n'))!=NULL)
       {
          *s1='\0';
          break;
       }
    }
    if(tmp) /* resize the allocated space to string length */
       if((tmp= realloc(s,strlen(s)+1))!=NULL)
          s = tmp;
    if(!tmp)
    { /* Oops! stream read error or allocation failure */
       free(s);
       s=NULL;
    }
    return s;
}

char *getline(void)
{
    return fgetline(stdin);
}

-- 
Al Bowers
Tampa, Fl USA
mailto: xabowers@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/


Relevant Pages