📄 ranges.c
字号:
#include <stdio.h>#include <stdlib.h>#include "ranges.h"void parse_range(char *str, int *low, int *high, int *modulus)/* Parses a string of the following form: [@][low][:[high]][+modulus], where 'low' and 'high' must be a non-negative integers; 'modulus' must be a positive integer. If 'low' is omitted, it defaults to one (not zero, even though zero is a legal value). If 'modulus' is omitted, it defaults to zero. If 'high' is omitted but the colon or a modulus is present, 'high' is set to -1 as a signal to the caller. If just a single number appears, it is interpreted as a value for 'low', and 'high' is set to -2. If an initial @ appears, '-low' is returned instead of 'low'. Something must appear (i.e. the empty string is not legal). The caller provides pointers to places to store 'low', 'high', and 'modulus'. The pointer for 'modulus' may be null, in which case a modulus specification is illegal. Incorrect specifications lead to an error message being displayed, and the program being terminated. The checks include verifying that low<=high when 'high' is specified, but the caller may need to check this also after in cases where 'high' is left to default. */{ char *s; s = str; if (*s==0) goto error; if (*s=='@') s += 1; /* skip an initial '@' */ *low = 1; /* look for value for 'low', or let it default */ if (*s>='0' && *s<='9') { *low = 0; while (*s>='0' && *s<='9') { *low = 10*(*low) + (*s-'0'); s += 1; } } if (*str=='@') *low = -*low; /* negate low iff leading '@' */ *high = *s==0 ? -2 : -1; /* look for value for 'high', */ if (*s==':') { /* or signal its absence */ s += 1; if (*s!=0 && *s>='0' && *s<='9') { *high = 0; while (*s>='0' && *s<='9') { *high = 10*(*high) + (*s-'0'); s += 1; } if (*high<*low){ fprintf(stderr,"High end of range is less than low end: %s\n",str); exit(1); } } } if (modulus!=0) *modulus = 0; /* look for value for 'modulus' */ if (*s=='+') { /* if it's legal, or let it default */ if (modulus==0) goto error; s += 1; *modulus = 0; while (*s>='0' && *s<='9') { *modulus = 10*(*modulus) + (*s-'0'); s += 1; } if (*modulus==0) goto error; } if (*s!=0) goto error; /* check for garbage at end */ return;error: /* report error */ fprintf(stderr,"Bad range specification: %s\n",str); exit(1);}void parse_length(char *str, int *length, int *modulus)/* Parses a string of the following form: [@]length[{%|+}modulus], where 'length' must be a non-negative integer; 'modulus' must be a positive integer. If the optional initial @ was found, then -length is returned to signal this. 'modulus' defaults to 1. If a + was given instead of a %, then -modulus is retuned; The caller provides pointers to places to store 'length' and 'modulus'. Incorrect specifications lead to an error message being displayed, and the program being terminated. */{ char *s; int neg = 0; s = str; if (*s==0) goto error; if (*s=='@') s += 1; /* skip an initial '@' */ *length = 0; while (*s>='0' && *s<='9') { *length = 10*(*length) + (*s-'0'); s++; } if (*length==0) goto error; if (*str=='@') *length = -*length; /* negate iff leading '@' */ *modulus = 1; /* look for value for 'modulus', or let it default */ if (*s=='%' || *s=='+') { if (*s=='+') neg = 1; s += 1; *modulus = 0; while (*s>='0' && *s<='9') { *modulus = 10*(*modulus) + (*s-'0'); s++; } if (*modulus==0) goto error; if (neg) *modulus = -*modulus; } if (*s!=0) goto error; /* check for garbage at end */ return;error: /* report error */ fprintf(stderr,"Bad length specification: %s\n",str); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -