fork download
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. // int alpha_range(char c) { return 0 != strchr("abcdefghijklmnopqrstuvwxyz", c); }
  6. // int digit_range(char c) { return 0 != strchr("0123456789", c); }
  7.  
  8. int alpha_range(char c) { return (c>='a') && (c<='z'); }
  9. int digit_range(char c) { return (c>='0') && (c<='9'); }
  10.  
  11. char* expand(const char* s)
  12. {
  13. char buf[2048];
  14.  
  15. const char* in = s;
  16. char* out = buf;
  17.  
  18. // parser state
  19. int (*predicate)(char) = 0; // either: NULL (free state), alpha_range (in alphabetic range), digit_range (in digit range)
  20. char lower=0,upper=0; // tracks lower and upper bound of character ranges in the range parsing states
  21.  
  22. // init
  23. *out = 0;
  24.  
  25. while (*in)
  26. {
  27. if (!predicate)
  28. {
  29. // free parsing state
  30. if (alpha_range(*in) && (in[1] == '-') && alpha_range(in[2]))
  31. {
  32. lower = upper = *in++;
  33. predicate = &alpha_range;
  34. }
  35. else if (digit_range(*in) && (in[1] == '-') && digit_range(in[2]))
  36. {
  37. lower = upper = *in++;
  38. predicate = &digit_range;
  39. }
  40. else *out++ = *in;
  41. } else
  42. {
  43. // in a range
  44. if (*in < lower) lower = *in;
  45. if (*in > upper) upper = *in;
  46.  
  47. if (in[1] == '-' && predicate(in[2]))
  48. in++; // more coming
  49. else
  50. {
  51. // end of range mode, dump expansion
  52. char c;
  53. for (c=lower; c<=upper; *out++ = c++);
  54. predicate = 0;
  55. }
  56. }
  57. in++;
  58. }
  59.  
  60. *out = 0; // null-terminate buf
  61. return strdup(buf);
  62. }
  63.  
  64. void dotest(const char* const input)
  65. {
  66. char* ex = expand(input);
  67. printf("input : '%s'\noutput: '%s'\n\n", input, ex);
  68.  
  69. if (ex)
  70. free(ex);
  71. }
  72.  
  73. int main (int argc, char *argv[])
  74. {
  75. dotest("a-z or 0-9 or a-b-c or a-z0-9"); // from the original post
  76. dotest("This is some e-z test in 5-7 steps; this works: a-b-c. This works too: b-k-c-e. Likewise 8-4-6"); // from my C++ answer
  77. dotest("-x-s a-9 9- a-k-9 9-a-c-7-3"); // assorted torture tests
  78.  
  79. return 0;
  80. }
  81.  
Success #stdin #stdout 0s 1852KB
stdin
Standard input is empty
stdout
input : 'a-z or 0-9 or a-b-c or a-z0-9'
output: 'abcdefghijklmnopqrstuvwxyz or 0123456789 or abc or abcdefghijklmnopqrstuvwxyz0123456789'

input : 'This is some e-z test in 5-7 steps; this works: a-b-c. This works too: b-k-c-e. Likewise 8-4-6'
output: 'This is some efghijklmnopqrstuvwxyz test in 567 steps; this works: abc. This works too: bcdefghijk. Likewise 45678'

input : '-x-s a-9 9- a-k-9 9-a-c-7-3'
output: '-stuvwx a-9 9- abcdefghijk-9 9-abc-34567'