9Feb/090
A Simple Weird Sorter
This is a little toy program written for one of my CS classes. The program takes a positive integer N as an argument and reads from stdin until it gets an EOF. The program then sorts the input using qsort, while assuming that each element to be supported is N bytes long.
Fun facts: the output from this program looks kinda cool if you do "./program_name 1 < index.html" where index.html is some large webpage.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #define MEM_SIZE 100 // for the sake of ease, token length and input array are global unsigned long global_token; char * in_ptr; // comparator for qsort, // returns 1 if a is bigger, -1 is smaller, 0 if equal int comparator(const void * a, const void * b) { unsigned int i; int r_value = 0; for(i = 0; i < global_token; ++i) { if( *(i + (char*)a) < *(i + (char*)b)) return -1; else if ( *(i + (char*)a) > *(i + (char*)b)) return 1; } return 0; } // get input from stdin and save it to dynmaically allocated memory unsigned long get_input() { char* temp_in_ptr; unsigned long ar_size, n_ar_size; unsigned long max_size = MEM_SIZE; for(ar_size = 0; !feof(stdin); ++ar_size) // loop until EOF { if(max_size == (1 + ar_size)) // check if more memory is needed { temp_in_ptr =(char *)realloc(in_ptr, (size_t)(MEM_SIZE + max_size)); if(!temp_in_ptr) // returns error and exits if realloc fails { fprintf(stderr, "Error in allocating memory for input."); fprintf(stderr, "Input data may be too large.\n"); free(in_ptr); // free dynamically allocated memory exit(1); } in_ptr = temp_in_ptr; max_size += MEM_SIZE; } *(in_ptr + ar_size) = fgetc(stdin); // get next char from input if(ferror(stdin)) // check for read error { fprintf(stderr, "Error encountered in reading input.\n"); free(in_ptr); // free dynamically allocated memory exit(1); } } ar_size --; // get rid of EOF char // if string was not multiple of token length, need to make it // a multiple of token length and fill end with '\0' if(ar_size % global_token != 0) { n_ar_size = (global_token * (unsigned int)(ar_size / global_token + 1)); if(n_ar_size > max_size) // check if more memory is needed { temp_in_ptr = (char *)realloc(in_ptr, (size_t)n_ar_size); if(!temp_in_ptr) // check for error in mem allocation { fprintf(stderr, "Error in allocating memory for input."); fprintf(stderr, "Input data may be too large.\n"); free(in_ptr); // free dynamically allocated memory exit(1); } in_ptr = temp_in_ptr; } for(; ar_size != n_ar_size; ++ar_size) // fill with '\0' { *(ar_size + in_ptr) = '\0'; } } return ar_size; } int main(int argc, char** argv) { unsigned long ar_size, i; in_ptr = (char *)malloc(MEM_SIZE * sizeof(char)); if (argc < 2) { fprintf(stderr, "Must provide at least one argument.\n"); free(in_ptr); // free dynamically allocated memory exit(1); } // use strtoul() to convert char to long int // and use errno to check for error in conversion errno = 0; global_token = strtoul(*(argv + 1), NULL, 0); if(!global_token || errno == ERANGE) { fprintf(stderr, "Argument must be a positive integer.\n"); free(in_ptr); // free dynamically allocated memory exit(1); } ar_size = get_input(); // get data from stdin // sort with qsort qsort(in_ptr, (size_t)(ar_size / global_token), (size_t)(sizeof(char) * global_token) , comparator); for(i = 0; i < ar_size; ++i) //print sorted data { printf("%c", *(in_ptr + i)); } free(in_ptr); // free dynamically allocated memory return 0; }