Page 63
Write a function expand(s1,s2)
that expands shorthand notations like a-z
in the
string s1
into the equivalent complete list abc...xyz
in s2
. Allow for letters
of either case and digits, and be prepared to handle cases like a-b-c
and a-z0-9
and -a-z
. Arrange that a leading or trailing -
is taken literally.
#include <stdio.h>
#define LEN 1000
void expand(char s1[], char s2[]);
int main()
{
char s1[] =
"Lowercase: a-z\nUppercase: A-Z\nNumeric: 0-9\nAll: a-zA-Z0-9\nPre/post-fixes: -a-z A-Z-a\nRed herrings: a-b-c 0-z a-9 a-Z";
char s2[LEN];
expand(s1, s2);
printf("%s", s2);
}
/* Only handles sequences in order! */
void expand(char s1[], char s2[])
{
enum states { DEFAULT, LOWER, UPPER, NUMERIC };
char c, c1, c2, k;
int i, j;
char begin, end;
enum states state = DEFAULT;
for (i = j = 0; (c = s1[i]) != '\0'; i++) {
if (state == DEFAULT) {
/* Hyphen triggers state transition if previous character valid */
if (c == '-') {
if (c1 >= 'a' && c1 <= 'z') {
state = LOWER;
} else if (c1 >= 'A' && c1 <= 'Z') {
state = UPPER;
} else if (c1 >= '0' && c1 <= '9') {
state = NUMERIC;
} // else state remains DEFAULT
}
} else {
/* Execute state action if terminating character valid */
if ((state == LOWER && c >= 'a' && c <= 'z') ||
(state == UPPER && c >= 'A' && c <= 'Z') ||
(state == NUMERIC && c >= '0' && c <= '9')) {
/* Start at c2 + 1 as c2 already pushed before state transition
* End at c - 1 as c will be pushed at the end of this loop */
for (k = c2 + 1; k <= c - 1; k++) {
s2[j++] = k;
}
} else {
/* Terminating character invalid, ensure '-' is pushed */
s2[j++] = '-';
}
state = DEFAULT;
}
if (state == DEFAULT) {
s2[j++] = c;
}
c2 = c1;
c1 = c;
}
s2[j] = '\0';
}