Last active
August 21, 2017 07:44
-
-
Save HorlogeSkynet/67d8e00f8dd0945ec9288bfb445ff53f to your computer and use it in GitHub Desktop.
A simple program which sorts a text file alphabetically (one string per line), with the Shell sort algorithm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <inttypes.h> | |
| #include <errno.h> | |
| #define BUFFERSIZE 64 | |
| void shellSort(const char *const); | |
| void closeFile(FILE**); | |
| int main(int argc, const char *argv[]) | |
| { | |
| (void)argc; | |
| (void)argv; | |
| if(argc == 2 && argv[1] != NULL) | |
| { | |
| shellSort(argv[1]); | |
| } | |
| else | |
| { | |
| fprintf(stderr, "ERROR, nothing to sort...\n"); | |
| } | |
| return 0; | |
| } | |
| void shellSort(const char *const filePath) | |
| { | |
| // Let's open the file with strings not alphabetically sorted, in reading mode. | |
| FILE *file = fopen(filePath, "r"); | |
| if(file == NULL) | |
| { | |
| fprintf(stderr, "ERROR, Couldn\'t open \"%s\" as well: %s.\n", filePath, strerror(errno)); | |
| return; | |
| } | |
| char buffer[BUFFERSIZE] = ""; | |
| // Let's count the number of lines the file contained. | |
| uint16_t nbLines = 0; | |
| while(fgets(buffer, BUFFERSIZE, file)) | |
| { | |
| nbLines++; | |
| } | |
| // Let's go back to the beginning ! | |
| rewind(file); | |
| // Let's allocate a memory space for an array of strings. | |
| char **data = (char**)calloc(nbLines, sizeof(*data)); | |
| if(data == NULL) | |
| { | |
| fprintf(stderr, "ERROR, Coulnd\'t allocate memory for data.\n"); | |
| closeFile(&file); | |
| return; | |
| } | |
| for(uint16_t i = 0; i < nbLines; i++) | |
| { | |
| data[i] = (char*)calloc(BUFFERSIZE, sizeof(*data[i])); | |
| if(data[i] == NULL) | |
| { | |
| fprintf(stderr, "ERROR, Coulnd\'t allocate memory for data.\n"); | |
| for(int16_t j = i - 1; j >= 0; j--) | |
| { | |
| free(data[j]); | |
| data[j] = NULL; | |
| } | |
| free(data); | |
| data = NULL; | |
| closeFile(&file); | |
| return; | |
| } | |
| } | |
| // Let's fill in the array with the strings from the file ! | |
| for(uint16_t i = 0; i < nbLines; i++) | |
| { | |
| fgets(buffer, BUFFERSIZE, file); | |
| strncpy(data[i], buffer, BUFFERSIZE); | |
| } | |
| // Let's compute a 'gap' which fits the best with our case. | |
| uint8_t gap = 1; | |
| while(gap <= nbLines / 3) | |
| { | |
| gap = gap * 3 + 1; | |
| } | |
| uint16_t inner, outer; | |
| while(gap > 0) | |
| { | |
| for(outer = gap; outer < nbLines; outer++) | |
| { | |
| strncpy(buffer, data[outer], BUFFERSIZE); | |
| inner = outer; | |
| while(inner > gap - 1 && strcmp(data[inner - gap], buffer) > 0) | |
| { | |
| strncpy(data[inner], data[inner - gap], BUFFERSIZE); | |
| inner -= gap; | |
| } | |
| strncpy(data[inner], buffer, BUFFERSIZE); | |
| } | |
| gap = (gap - 1) / 3; | |
| } | |
| closeFile(&file); | |
| // Let's re-open this file in writing mode ! | |
| file = fopen(filePath, "w"); | |
| if(file == NULL) | |
| { | |
| fprintf(stderr, "ERROR, Coulnd\'t open the file as well: %s\n", strerror(errno)); | |
| return; | |
| } | |
| // Writes down the string (alphabetically sorted) in the file ! | |
| for(uint16_t i = 0; i < nbLines; i++) | |
| { | |
| fputs(data[i], file); | |
| } | |
| closeFile(&file); | |
| // Dis-allocate the array of strings. | |
| for(uint16_t i = 0; i < nbLines; i++) | |
| { | |
| free(data[i]); | |
| data[i] = NULL; | |
| } | |
| free(*data); | |
| *data = NULL; | |
| } | |
| void closeFile(FILE **file) | |
| { | |
| if(fclose(*file) == EOF) | |
| { | |
| fprintf(stderr, "ERROR, Coulnd\'t close the file as well: %s\n", strerror(errno)); | |
| } | |
| *file = NULL; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment