⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sscanf.c

📁 类PASCAL语言的编译器,LINUX环境的,我没试过是否正确.
💻 C
字号:
#include <limits.h>#include <stdio.h>#include <string.h>#include "script.h"#define	inchar()	((c = string[pos++]),                \			 pos>stringlen ?                \			 EOF : (++read_in, c))#define	conv_error()	return(done)#define input_error()	return(-1)#define	memory_error()	return(-1)#define SCALL(x)        if(x) return -1;/* Read formatted input from String according to the format string   FORMAT, using the argument list in ARG.   Return the number of assignments made, or -1 for an input error.  */longSscanf(struct Data *scr,       uchar *string,       uchar *format,       long argc,       void **param_array,       uchar *param_types){  struct Identifier *ident;  long stringlen = string?FPL_STRLEN(string):0; /* length of string to parse */  long pos=0; /* current scan point! */  char *f = format;  char fc;		/* Current character of the format.  */  long done = 0;	/* Assignments done.  */  long read_in = 0;	/* Chars read in.  */  long c;		/* Last char read.  */  long do_assign;	/* Whether to do an assignment.  */  long width;		/* Maximum field width.  */  /* Type modifiers.  */  char is_short, is_long, is_long_double;#ifdef	HAVE_LONGLONG      /* We use the `L' modifier for `long long int'.  */#define	is_longlong	is_long_double#else#define	is_longlong	0#endif  /* If a [...] is a [^...].  */  char not_in;  /* Base for integral numbers.  */  long base;  /* Integral holding variables.  */  long num;  unsigned long unum;  /* Workspace.  */  char work[200];  char *w;		/* Pointer into WORK.  */  long param_num = 1; /* start on (0 and 1 is the first strings) 2nd param! */  if (format == NULL) {    input_error();  }  c = inchar();  /* Run through the format string.  */  while (*f != '\0') {    fc = *f++;    if (fc != '%') {      /* Characters other than format specs must just match.  */      if (c == EOF)	  input_error();      if (isspace(fc)) {	/* Whitespace characters match any amount of whitespace.  */	while (isspace (c))	    inchar ();	continue;      }      else if (c == fc)	  (void) inchar();      else	  conv_error();      continue;    }    /* Check for the assignment-suppressant.  */    if (*f == '*') {      do_assign = 0;      ++f;    }    else	do_assign = 1;		    /* Find the maximum field width.  */    width = 0;    while (isdigit(*f)) {      width *= 10;      width += *f++ - '0';    }    if (width == 0)	width = -1;    /* Check for type modifiers.  */    is_short = is_long = is_long_double = 0;    while (*f == 'h' || *f == 'l' || *f == 'L')	switch (*f++) {	case 'h':#if 0	  /* int's are short int's.  */	  is_short = 1;	  break;#endif	case 'l':#if 0	  if (is_long)	      /* A double `l' is equivalent to an `L'.  */	      is_longlong = 1;	  else	      /* int's are long int's.  */	      is_long = 1;	  break;#endif	case 'L':#if 0	  /* double's are long double's, and int's are long long int's.  */	  is_long_double = 1;#endif	  break;	}    /* End of the format string?  */    if (*f == '\0')	conv_error();    /* Find the conversion specifier.  */    w = work;    fc = *f++;    if (fc != '[' && fc != 'c' && fc != 'n')	/* Eat whitespace.  */	while (isspace(c))	    (void) inchar();    switch (fc) {    case '%':	/* Must match a literal '%'.  */      if (c != fc)	  conv_error();      break;    case 'n':	/* Answer number of assignments done.  */      if (do_assign) {	if(++param_num>=argc)	    return -1;	if(param_types[param_num] == FPL_INTVARARG) {	  ident = (struct Identifier *) param_array[param_num];	  ident->data.variable.var.val32[0] = read_in;	}	else	    conv_error();      }      break;    case 'c':	/* Match characters.  */      if (do_assign) {	if(++param_num>=argc)	    return -1;	if(param_types[param_num] == FPL_STRVARARG) {	  ident = (struct Identifier *) param_array[param_num];	  if(ident->data.variable.var.str[0])	      FREE_KIND(ident->data.variable.var.str[0]);	  ident->data.variable.var.str[0]=NULL;	}	else	    conv_error();      }      if (c == EOF)	  input_error();      if (width == -1)	  width = 1;      if (do_assign) {	SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0],			   ADD_RESET));	do {	  SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0], c));	} while (inchar() != EOF && --width > 0);      }      else	  while (inchar() != EOF && width > 0)	      --width;            if (do_assign) {	SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0], ADD_FLUSH));	++done;      }      if (c == EOF)	  input_error();      break;          case 's':	/* Read a string.  */      if (do_assign) {	if(++param_num>=argc)	    return -1;	if(param_types[param_num] == FPL_STRVARARG) {	  ident = (struct Identifier *) param_array[param_num];	  if(ident->data.variable.var.str[0])	      FREE_KIND(ident->data.variable.var.str[0]);	  ident->data.variable.var.str[0]=NULL;	}	else	    conv_error();      }      if (c == EOF)	  input_error();      if(do_assign) {	SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0],			   ADD_RESET));      }      do {	if (isspace(c))	    break;	if (do_assign) {	  SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0], c));	}      } while (inchar() != EOF && (width <= 0 || --width > 0));      if (do_assign) {	SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0], ADD_FLUSH));	++done;      }      break;    case 'x':	/* Hexadecimal integer.  */    case 'X':	/* Ditto.  */       base = 16;      goto number;    case 'o':	/* Octal integer.  */      base = 8;      goto number;    case 'u':	/* Decimal integer.  */    case 'd':	/* Ditto.  */      base = 10;      goto number;    case 'i':	/* Generic number.  */      base = 0;    number:;      if (c == EOF)	  input_error();      /* Check for a sign.  */      if (c == '-' || c == '+') {	*w++ = c;	if (width > 0)	    --width;	(void) inchar();      }      /* Look for a leading indication of base.  */      if (c == '0') {	if (width > 0)	    --width;	*w++ = '0';	(void) inchar();	if (tolower(c) == 'x') {	  if (base == 0)	      base = 16;	  if (base == 16) {	    if (width > 0)		--width;	    (void) inchar();	  }	}	else if (base == 0)	    base = 8;      }      if (base == 0)	  base = 10;      /* Read the number into WORK.  */      do {	if (base == 16 ? !isxdigit(c) :	    (!isdigit(c) || c - '0' >= base))	    break;	*w++ = c;	if (width > 0)	    --width;      } while (inchar() != EOF && width != 0);      if (w == work ||	  (w - work == 1 && (work[0] == '+' || work[0] == '-')))	  /* There was on number.  */	  conv_error();      /* Convert the number.  */      *w = '\0';      num = Strtol(work, base, &w);      if (w == work)	  conv_error();      if (do_assign) {	if(++param_num>=argc)	    return -1;	if(param_types[param_num] == FPL_INTVARARG) {	  ident = (struct Identifier *) param_array[param_num];	  ident->data.variable.var.val32[0] = num;	}	else	    conv_error();	++done;      }      break;    case '[':	/* Character class.  */      if (do_assign) {	if(++param_num>=argc)	    return -1;	if(param_types[param_num] == FPL_STRVARARG) {	  ident = (struct Identifier *) param_array[param_num];	  if(ident->data.variable.var.str[0])	      FREE_KIND(ident->data.variable.var.str[0]);	  ident->data.variable.var.str[0]=NULL;	}	else	    conv_error();      }      if (c == EOF)	  input_error();      if (*f == '^') {	++f;	not_in = 1;      }      else	  not_in = 0;      while ((fc = *f++) != '\0' && fc != ']') {	if (fc == '-' && *f != '\0' && *f != ']' &&	    w > work && w[-1] <= *f)	    /* Add all characters from the one before the '-'	       up to (but not including) the next format char.  */	    for (fc = w[-1] + 1; fc < *f; ++fc)		*w++ = fc;	else	    /* Add the character to the list.  */	    *w++ = fc;      }      if (fc == '\0')	  conv_error();      *w = '\0';      unum = read_in;      if(do_assign) {	SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0],			   ADD_RESET));      }      do {	if ((strchr(work, c) == NULL) != not_in)	    break;	if (do_assign) {	  SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0], c));	}	if (width > 0)	    --width;      } while (inchar() != EOF && width != 0);      if (read_in == unum)	  conv_error();      if (do_assign) {	SCALL(AddCharBuffer(scr, &ident->data.variable.var.str[0], ADD_FLUSH));	++done;      }      break;    case 'p':	/* Generic pointer.  */      base = 16;      /* A PTR must be the same size as a `long int'.  */      is_long = 1;      goto number;    }  }  conv_error();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -