123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- //This is a trivial C program that takes as input a string of the
- //form: "[a-zA-Z0-9]-[a-zA-Z0-9]". It then expands. eg:
- // "a-e2-4" will expand into "abcde234"
- // We will hereafter refer to any three length strength of the form:
- // "[a-zA-Z0-9]-[a-zA-Z0-9]" a sequence.
- //This exercise is taken from "The C Programming Language" p. 63
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #define ALLOCATE_SEQUENCE() (struct sequence_t *) \
- malloc (sizeof (struct sequence_t))
- /* This would expand the sequence "a-e" into "abcde". This macro
- works on one sequence at a time. So it will not process two
- sequences like "a-e4-6" at once. It returns a pointer to the
- expanded string. */
- #define EXPAND_SEQUENCE_TO_STRING(loop_str) \
- for (char c = sequence->beginning_char; \
- c <= sequence->end_char; c++, i++) \
- *(loop_str + i) = c; \
- *(loop_str + i) = '\0';
- #define IS_CHAR_A_DIGIT(c) (c >= '0' && c <= '9') ? 1 : 0
- #define EXIT_IF_INVALID_SEQUENCE(a, b) \
- if ((isalpha (a) && !(isalpha (b))) \
- || (isdigit (a) && !(isdigit (b))) \
- || (isupper (a) && (islower (b))) \
- || (islower (a) && (isupper (b)))) \
- { \
- fprintf (stderr, "Input String \"%c-%c\" is not valid\n", \
- a, b); \
- fprintf (stderr, \
- "Sequences are of the form ([a-bA-B0-9]-[a-bA-B0-9])+.\n"); \
- exit (EXIT_FAILURE); \
- }
- /* This is the number of sequences the inputted string has. */
- int sequences = 0;
- /* sequence_t will store the information from an encoded string the
- ** encoded strings looks like "[a-zA-Z0-9]-[a-zA-Z0-9]". So an
- ** encoded string of "a-z", represents the whole alphabet. */
- //A struct of
- //sequence_t = {beginning_char = 'a', end_char = 'z', next
- // = sequence_t { beginning_char = '0', end_char = '9', next = 0 }}
- // represents a string that contains the alphabet followed by the
- // numbers 1-9. The original string would have been "a-z0-9".
- struct sequence_t
- {
- char beginning_char, end_char;
- unsigned int sequence_length;
- struct sequence_t *next;
- };
- void *
- xmalloc (size_t size)
- {
- void *value = malloc (size);
- if (value == 0)
- {
- fprintf (stderr, "virtual memory exhausted\n");
- exit (EXIT_FAILURE);
- }
- return value;
- }
- /* This function parses the string of sequences into numerous struct
- sequence_t. It returns the pointer to the first sequence. */
- struct sequence_t * parse_string (char * input_string)
- {
- int str_len = strlen (input_string);
- if (str_len % 3)
- {
- fprintf
- (stderr,
- "Sequences are of the form ([a-bA-B0-9]-[a-bA-B0-9])+.\n");
- exit (EXIT_FAILURE);
- }
- // This is the number of sequences that we have. (reminder "a-c0-9"
- //is 2 sequences).
- extern int sequences;
- sequences = str_len / 3;
- struct sequence_t * sequence = ALLOCATE_SEQUENCE ();
- struct sequence_t * loop_sequence = sequence;
- for (int i, j = 0; j < sequences; i++, j++)
- {
- loop_sequence->beginning_char = *(input_string + i);
- i += 2; //skip the '-'
- loop_sequence->end_char = *(input_string + i);
- EXIT_IF_INVALID_SEQUENCE
- (sequence->beginning_char, sequence->end_char);
- loop_sequence->next = ALLOCATE_SEQUENCE ();
- loop_sequence = loop_sequence->next;
- }
- return sequence;
- }
- /* This function returns expanded sequences from the inputted string
- of sequences. */
- char * expand (char * input_string)
- {
- struct sequence_t * sequence = parse_string (input_string);
- extern int sequences;
- //this is using way too much memory. For the sequence "a-b", 32
- //chars are allocated for it.
- char * return_string = (char *) xmalloc (sizeof (char) * 32 * sequences);
- int return_string_len = 0;
- int i;
- //this should work in place of the next line...memset (loop_str, 0, 32);
- char * loop_str = (char *) xmalloc (sizeof (char) * 32);
- while (sequence)
- {
- i = 0;
- EXPAND_SEQUENCE_TO_STRING (loop_str);
- strcpy ((return_string + return_string_len), loop_str);
- return_string_len += i;
- sequence = sequence->next;
- }
- free (loop_str);
- return return_string;
- }
- int main ()
- {
- char * expanded_string = expand ("1-3a-gM-T3-5");
- printf ("%s\n", expanded_string);
- return 0;
- }
|