By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,654 Members | 936 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,654 IT Pros & Developers. It's quick & easy.

having problems with interactive error catching function

P: n/a
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);
}

Nov 14 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On Thu, 1 Jan 2004 12:36:19 -0600, "interpim" <le***@atrc.navy.mil>
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?
Use strtol instead of sscanf and check the "updated" pointer to make
sure it points to the end of your string and not to an intermediate
non-integer.

#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);
}


<<Remove the del for email>>
Nov 14 '05 #2

P: n/a
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);
}


Please fix your line length. It should never exceed 80, and 65 is
about optimum.

Look up the %n specifier, which will show where the conversion
stopped. You can then examine the remainder of the input string,
to see if it consists of anything other than white space, and
object if desired. From N869:

n No input is consumed. The corresponding argument
shall be a pointer to signed integer into which is
to be written the number of characters read from the
input stream so far by this call to the fscanf
function. Execution of a %n directive does not
increment the assignment count returned at the
completion of execution of the fscanf function. No
argument is converted, but one is consumed. If the
conversion specification includes an assignment-
suppressing character or a field width, the behavior
is undefined.

An alternative is to use strtol(), which can also return a pointer
past the converted value, and is probably clearer. I am not sure
whether or not strtoul() will object to a leading - sign, or
simply do the unsigned modulo operations. At any rate using
either also allows you to put firm limitations on the input range.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #3

P: n/a


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: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #4

P: n/a
in comp.lang.c i read:
char line[MAXLINE];
int error,n;
do{
printf("Input a positive integer: ");
fgets(line, MAXLINE, stdin);
error=sscanf(line, "%d",&n) !=1||n<=0;


in addition to the other comments i'll add that if fgets reaches eof or
encounters an error line will not have been modified, and if this happens
on the first iteration the content would (continue to) be indeterminate so
calling sscanf would have undefined behavior. the solution is to check the
return value from fgets, e.g.,

if (0 == fgets(line, sizeof line, stdin)) break;

if you do this you must ensure that code following your loop doesn't depend
on line, error or n having a value, e.g.,

} while(error);
if (ferror(stdin)) fputs("error reading stdin\n", stderr), abort();
if (feof(stdin)) fputs("unexpected eof reading stdin\n", stderr), abort();

--
a signature
Nov 14 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.