| | |
Implementing scanf with getchar
Please support our C advertiser: Programming Forums - DaniWeb Sister Site
![]() |
•
•
Join Date: Jan 2008
Posts: 3
Reputation:
Solved Threads: 0
//I tried to fix the errors but I failed.
//pls do it for me.......
//pls do it for me.......
c Syntax (Toggle Plain Text)
#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 Ancient Dragon; Feb 15th, 2008 at 10:09 am. Reason: add code tags
Use code tags. Mention specific problems and the line no.s. The size of the code is a bit too lengthy. Proper formatting and specific questions would take you a long way ahead in getting help.
"You know you're a computer geek when you try to shoo a fly away from the monitor screen with your cursor. That just happened to me. It was scary." - Juuso Heimonen.
"The only truly secure computer is one buried in concrete, with the power turned off and the network cable cut." - Anonymous.
"The only truly secure computer is one buried in concrete, with the power turned off and the network cable cut." - Anonymous.
what are a few of the error messages you got ? What compiler are you using ? My guess is that you did not write the code you posted because its too advanced for someone that asked the question you asked.
The code appears to have been written with Turbo C compiler ( clrscr() is only supported by Turbo C) so you will have to rewrite parts of that code that contains Borland-specific functions.
The code appears to have been written with Turbo C compiler ( clrscr() is only supported by Turbo C) so you will have to rewrite parts of that code that contains Borland-specific functions.
Last edited by Ancient Dragon; Feb 15th, 2008 at 10:22 am.
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
That looks like a healthy mix up of scanf and printf. Why are you trying to do padding in scanf? That code is actually quite awful, so you probably want to redesign and rewrite it. I get the impression that this isn't your code, so I'll give you a better example to start with:
c Syntax (Toggle Plain Text)
#include <ctype.h> #include <stdio.h> #include <stdarg.h> int myscanf ( const char *fmt, ... ); static int trim_leading ( void ); static int myscanf_internal ( const char *fmt, va_list args ); int main ( void ) { char s[100]; int a; myscanf ( "%s%d", s, &a ); printf ( "%s\n%d\n", s, a ); return 0; } int myscanf ( const char *fmt, ... ) { va_list args; int rv; va_start ( args, fmt ); rv = myscanf_internal ( fmt, args ); va_end ( args ); return rv; } static int trim_leading ( void ) { int ch; do { if ( ( ch = getchar() ) == EOF ) break; } while ( isspace ( ch ) ); ungetc ( ch, stdin ); return ch; } static int myscanf_internal ( const char *fmt, va_list args ) { int converted = 0; while ( *fmt != '\0' ) { if ( *fmt++ == '%' ) { switch ( *fmt ) { case 's': { char *dst = va_arg ( args, char* ); int ch; trim_leading(); while ( ( ch = getchar() ) != EOF && !isspace ( ch ) ) *dst++ = (char)ch; *dst = '\0'; ++converted; } break; case 'd': { int neg = 0; int dst = 0; int ch; int i; trim_leading(); for ( i = 0; ( ch = getchar() ) != EOF; i++ ) { if ( i == 0 && ( ch == '-' || ch == '+' ) ) { neg = ( ch == '-' ); continue; } if ( !isdigit ( ch ) ) { ungetc ( ch, stdin ); break; } dst = 10 * dst + ( ch - '0' ); } if ( neg ) dst = -dst; *va_arg ( args, int* ) = dst; ++converted; } break; } } } return converted; }
I'm here to prove you wrong.
![]() |
Other Threads in the C Forum
- Previous Thread: Get the Makefile.am from the Makefile
- Next Thread: generic linked list
| Thread Tools | Search this Thread |
adobe api array arrays bash binarysearch calculate char cm convert copyanyfile copypdffile cprogramme createcopyoffile createprocess() csyntax directory dynamic feet fflush file floatingpointvalidation fork forloop frequency getlasterror givemetehcodez global graphics gtkgcurlcompiling hacking hardware highest homework i/o inches incrementoperators initialization intmain() iso km linked linkedlist linux linuxsegmentationfault list locate logical_drives loopinsideloop. match matrix microsoft motherboard mqqueue multi mysql oddnumber odf open opendocumentformat opensource openwebfoundation pattern pdf performance pointer pointers posix power program programming pyramidusingturboccodes read recursion recv recvblocked repetition scanf scheduling scripting segmentationfault send shape socketprograming socketprogramming stack standard strchr string strings suggestions test testautomation unix urboc user variable voidmain() win32api windows.h






