source code of scanf

Discussion in 'C' started by gyanu, Jan 31, 2008.

  1. gyanu

    gyanu New Member

    Joined:
    Jan 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    I want to create a new function myscanf (char *format,...) which does same as scanf() without using any library function other than getchar().
    Pls soomeone get it done for meeeeee.plssssssssssss
     
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Code:
    char c;
    do 
    {
        c=getchar();
        putchar (c);
    } while (c != '\n');
     
  3. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA

    You are still using library function getchar() and putchar().

    He is asking if i am correct.


    Code:
    #include "stddef.h"
    #include "stdarg.h"
    #include "stdlib.h"
    
    extern FILE *Stderr;
    
    
    int  MyScanf(char *s, const char *fmt, ...)
    {
    	char *s0;
    	va_list ap;
    	long L, *Lp;
    	int i, *ip, rc = 0;
    	va_start(ap, fmt);
    	for( ; ; ) {
    		for(;;) {
    			switch(i = *(unsigned char *)fmt++) {
    				case 0:
    					goto done;
    				case '%':
    					break;
    				default:
    					if (i <= ' ') {
    						while(*s <= ' ')
    							if (!*s++)
    								return rc;
    						}
    					else if (*s++ != i)
    						return rc;
    					continue;
    				}
    			break;
    			}
    		switch(*fmt++) {
    			case 'l':
    				if (*fmt != 'd')
    					bad(fmt);
    				fmt++;
    				Lp = va_arg(ap, long*);
    				L = strtol(s0 = s, &s, 10);
    				if (s > s0) {
    					rc++;
    					*Lp = L;
    					continue;
    					}
    				return rc;
    			case 'd':
    				ip = va_arg(ap, int*);
    				L = strtol(s0 = s, &s, 10);
    				if (s > s0) {
    					rc++;
    					*ip = (int)L;
    					continue;
    					}
    				return rc;
    			default:
    				bad(fmt);
    			}
    		}
     done:
    	return rc;
    	}
    	}
    
     
  4. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
    Oh!! At the last of code add one function

    va_end ( ap );
     
  5. gyanu

    gyanu New Member

    Joined:
    Jan 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1



    Shabbir bhai, hi
    U have helped me really.......... But my problem is not about supporting integer but rather %s,for string datatype char buf[100]
    %x, for hexadecimal
    %c for characters
    please help me little bit more
     
  6. gyanu

    gyanu New Member

    Joined:
    Jan 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    ansari bhai
    Thanks a lot .U r great but my problems are little more tough.I should not use myscanf(char *s,char *fmt,...)
    Also it should support %c,%x and %s for strings too
     
  7. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    I could not get you.
     
  8. oogabooga

    oogabooga New Member

    Joined:
    Jan 9, 2008
    Messages:
    115
    Likes Received:
    11
    Trophy Points:
    0
    Could we please see some of your code?
    I've seen this on another forum, and I've yet to see any code from you.
    People are not just going to do it for you (hopefully).
    If you want to cheat, look up some open source code for scanf.
     
  9. gyanu

    gyanu New Member

    Joined:
    Jan 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    I have to create and implement a function myscanf(char *format,...) wilthout using any library functions other than getchar().
    My program would support to undersand---------myscanf("%d%s%x",a,b[],c);
     
  10. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    The string parsing and variable number of arguments in a function is all together a diiferent topic and you can check out - OutputDebugString with variable number of arguments for that but I guess your initial requirement is fully satisfied with the code snippet I provided.
     
  11. asadullah.ansari

    asadullah.ansari TechCake

    Joined:
    Jan 9, 2008
    Messages:
    356
    Likes Received:
    14
    Trophy Points:
    0
    Occupation:
    Developer
    Location:
    NOIDA
    Really i am unable to understand what's your requirement!!!
     
  12. imrantechi

    imrantechi New Member

    Joined:
    Feb 12, 2008
    Messages:
    116
    Likes Received:
    4
    Trophy Points:
    0

    i feel this code is really self explanatary ,

    you can explain well
     
  13. gyanu

    gyanu New Member

    Joined:
    Jan 30, 2008
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    //please try to sort out the errors
    //I ve tried to make the function but has too much errors........
    //pls do it ....
    Code:
    #include<stdio.h>
    #include<conio.h>
    void main()
    {
    int a;
    void scanchar(char**);
    int scans(char**,char*,int,int);
    int scani(char**,int,int,int,int,int,int);
    int myscanf(char *);
    int smyscanf(char*,char*);
    clrscr();
    printf("enter");
    myscanf("%d",&a);
    printf("%d",a);
    getch();
    }
    static void scanchar(char **str)
    {
     extern int getchar();
     if (str) {
      **str = getchar();
      ++(*str);
     }
     else (void)getchar();
    }
    #define PAD_RIGHT 1
    #define PAD_ZERO 2
    static int prints(char **in, const char *string, int width, int pad)
    {
     register int sc = 0, padchar = ' ';
     if (width > 0) {
      register int len = 0;
      register const char *ptr;
      for (ptr = string; *ptr; ++ptr) ++len;
      if (len >= width) width = 0;
      else width -= len;
      if (pad & PAD_ZERO) padchar = '0';
     }
     if (!(pad & PAD_RIGHT)) {
      for ( ; width > 0; --width) {
       scanchar (in, padchar);
       ++sc;
      }
     }
     for ( ; *string ; ++string) {
      scanchar (in, *string);
      ++sc;
     }
     for ( ; width > 0; --width) {
      scanchar (in, padchar);
      ++sc;
     }
     return sc;
    }
    /* the following should be enough for 32 bit int */
    #define SCAN_BUF_LEN 12
    static int scani(char **in, int i, int b, int sg, int width, int pad, int letbase)
    {
     char scan_buf[SCAN_BUF_LEN];
     register char *s;
     register int t, neg = 0, sc = 0;
     register unsigned int u = i;
     if (i == 0) {
      scan_buf[0] = '0';
      scan_buf[1] = '\0';
      return scans (out, print_buf, width, pad);
     }
     if (sg && b == 10 && i < 0) {
      neg = 1;
      u = -i;
     }
     s = scan_buf + SCAN_BUF_LEN-1;
     *s = '\0';
     while (u) {
      t = u % b;
      if( t >= 10 )
       t += letbase - '0' - 10;
      *--s = t + '0';
      u /= b;
     }
     if (neg) {
      if( width && (pad & PAD_ZERO) ) {
       scanchar (in,'-');
       ++sc;
       --width;
      }
      else {
       *--s = '-';
      }
     }
     return sc + scans (in, s, width, pad);
    }
    static int scan(char **in, int *varg)
    {
     register int width, pad;
     register int sc = 0;
     register char *format = (char *)(*varg++);
     char scr[2];
     for (; *format != 0; ++format) {
      if (*format == '%') {
       ++format;
       width = pad = 0;
       if (*format == '\0') break;
       if (*format == '%') goto in;
       if (*format == '-') {
        ++format;
        pad = PAD_RIGHT;
       }
       while (*format == '0') {
        ++format;
        pad |= PAD_ZERO;
       }
       for ( ; *format >= '0' && *format <= '9'; ++format) {
        width *= 10;
        width += *format - '0';
       }
       if( *format == 's' ) {
        register char *s = *((char **)varg++);
        sc += scans (in, s?s:"(null)", width, pad);
        continue;
       }
       if( *format == 'd' ) {
        sc += scani (in, *varg++, 10, 1, width, pad, 'a');
        continue;
       }
       if( *format == 'x' ) {
        sc += scani (in, *varg++, 16, 0, width, pad, 'a');
        continue;
       }
       if( *format == 'X' ) {
        sc += scani (in, *varg++, 16, 0, width, pad, 'A');
        continue;
       }
       if( *format == 'u' ) {
        sc += scani (in, *varg++, 10, 0, width, pad, 'a');
        continue;
       }
       if( *format == 'c' ) {
        /* char are converted to int then pushed on the stack */
        scr[0] = *varg++;
        scr[1] = '\0';
        sc += scans (in, scr, width, pad);
        continue;
       }
      }
      else {
      in:
       scanchar (in, *format);
       ++sc;
      }
     }
     if (in) **in = '\0';
     return sc;
    }
    /* assuming sizeof(void *) == sizeof(int) */
    int myscanf(const char *format, ...)
    {
     register int *varg = (int *)(&format);
     return scan(0, varg);
    }
    int smyscanf(char *out, const char *format, ...)
    {
     register int *varg = (int *)(&format);
     return scan(&out, varg);
    }
     
    Last edited by a moderator: Feb 13, 2008

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice