T
Tarique
Barry said:....snip..
Sorry but you fixed only half the problem.
The Best i've come so far :I've re-designed the error handling (looks
sane to me! ) and now process signed "Longs" and "Ints" separately !
/*
* File: main.c
* Author: Tarique
*
* Created on July 4, 2008, 11:07 PM
*/
#include <stdio.h >
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdarg.h>
#include <errno.h >
/*
*
*/
struct ErrorCode {
int code ;
/*Pack any other info if required later on */
};
/*Provide Error Code to Differentiate between Errors*/
enum Ecodes {
E_OK = 0, /*Input Ok */
E_IO = 1, /*Input Stream Error */
E_EOF = 2, /*End of File Envountered */
E_TOOLONG = 3, /*Input Exceeds Buffer Length */
E_SHORTBUFF = 4, /*Destination Buffer is Short */
E_RANGE = 5, /*Number Exceeds Range */
E_BADINPUT = 6, /*Invalid Input Obtained */
E_DEFAULT = 7 /*All Unhandled Errors if Any */
};
/*
*If there is garbage in the input stream,pull off everything from the
*input stream to clear it for further use.
*/
int flushln(FILE *f) {
int ch;
while(('\n' != (ch = getc( f ))) && (EOF != ch))
;
return ch;
}
/*Takes a destination buffer and its size as arg (With Error Code) ;
*copies the user entered string into the destination buffer if input
* is successful and the caller's buffer is long enough to hold it.
*
*On Error ,clears the error and sets the appropriate error code which
*can be suitably utilized if necessary.
*/
void input( char* buff,
size_t buff_len,
struct ErrorCode* error ) {
#define BUFFSIZE 100 + 2
char buffer[ BUFFSIZE ];
char* p = buffer + BUFFSIZE - 1;
*p = !0;
if( fgets( buffer, BUFFSIZE, stdin ) == NULL ) {
if( ferror( stdin ) ) {
fprintf( stderr, "Input Stream Error \n" );
error->code = E_IO;
clearerr( stdin );
return ;
}
else if( feof( stdin ) ) {
fprintf( stderr, "EOF Encountered \n" );
error->code = E_EOF;
clearerr( stdin );
return ;
}
}
else {
if( !(*p || (*--p) == '\n') ) {
fprintf( stderr, "Too Long Input\n" );
error->code = E_TOOLONG;
flushln( stdin );
return ;
}
}
if( buff_len >= strlen(buffer) ) {
strcpy( buff, buffer );
error->code = E_OK;
return ;
}
else {
fprintf( stderr, "Too Long Input-b \n" );
error->code = E_SHORTBUFF;
return ;
}
}
/*
* If a string is successfully obtained from the input function,
*it is parsed using strtol. If no parsing error occurs, a long
*If there is any error zero is returned.
*/
long getLong(int isint,
struct ErrorCode* error ) {
char intbuff[21] = {0} ;
char* end_ptr = NULL;
long int lval = 0;
errno = 0;
printf("Enter :");
input( intbuff, 20, error );
if ( error->code == E_IO ) return 0;
else if( error->code == E_EOF ) return 0;
else if( error->code == E_TOOLONG ) return 0;
else if( error->code == E_SHORTBUFF ) return 0;
errno = 0;
lval = strtol( intbuff, &end_ptr, 10 );
if( ERANGE == errno ) {
fprintf(stderr,"Out of Range \n");
error->code = E_RANGE;
return 0;
}
else if (!((*end_ptr == '\n') || (*end_ptr == '\0') || (*end_ptr ==
' '))) {
error->code = E_BADINPUT;
fprintf( stderr, "Not a Valid Integer\n" );
return 0;
}
if(!isint) { /*Process long */
return lval;
}
else { /*Process Int*/
if ( lval > INT_MAX ) {
error->code = E_RANGE;
fprintf( stderr, "Number too Large \n" );
return 0;
}
else if ( lval < INT_MIN ) {
error->code = E_RANGE;
fprintf( stderr, "Number too Small \n" );
return 0;
}
else
return lval;
}
}
/*Minimal Scanf routine only for signed
*'ints' and 'longs' as of now
*/
int myscanf( const char* format, ... ) {
va_list ap ;
const char* p;
int count = 0;
int temp = 0;
long int temp_long = 0;
struct ErrorCode iserror;
iserror.code = 0;
va_start( ap, format );
for( p = format ; *p ; p++ ) {
if( *p != '%' ) {
continue;
}
switch( *++p ) {
case 'd' :
temp = (int)getLong( 0, &iserror );
if( !iserror.code ) {
*va_arg( ap, int* ) = temp;
count ++ ;
}
else {
*va_arg( ap, int* ) = 0;
iserror.code = 0;
}
break;
case 'l':
if( (*++p) == 'd' ) {
temp_long = getLong( 1, &iserror );
if( !iserror.code ) {
*va_arg( ap, long * ) = temp_long;
count ++;
}
else {
*va_arg( ap, long * ) = 0;
iserror.code = 0;
}
}
break;
default :
break;
}
}
va_end(ap);
return count;
}
int main( void ) {
long a = 0, b = 0;
int c = 0, d = 0;
myscanf("%ld %ld" ,&a ,&b);
printf("%d %d \n",a,b);
myscanf("%d %d" ,&c ,&d);
printf("%d %d\n",c,d);
return (EXIT_SUCCESS);
}
Tarique.