Skip to content

Instantly share code, notes, and snippets.

@HorlogeSkynet
Last active August 21, 2017 07:44
Show Gist options
  • Save HorlogeSkynet/67d8e00f8dd0945ec9288bfb445ff53f to your computer and use it in GitHub Desktop.
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
#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