/***************************************************************************
* Usage: sort input-file output-file
*
* Sort a list of real numbers in input-file, placing the results
* in output-file. Both input and output files contain one
* number per line.
*
* Arguments:
* input-file: file to be sorted
* output-file: file to receive the sorted list
*
* History:
* Date Name Modification
* 2017-08-24 Jason Bacon Begin
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
double *read_list(size_t *size, const char filename[]);
int print_list(const double list[], size_t list_size, const char filename[]);
void sort_list(double list[], size_t list_size);
void usage(void);
int main(int argc,char *argv[])
{
double *list;
size_t list_size;
int status = EX_OK;
char *input_file, // Just for readability
*output_file;
if ( argc != 3 )
usage();
input_file = argv[1];
output_file = argv[2];
list = read_list(&list_size, input_file);
if ( list == NULL )
{
perror(input_file);
return EX_NOINPUT;
}
sort_list(list, list_size);
if ( print_list(list, list_size, output_file) != EX_OK )
{
perror(output_file);
status = EX_CANTCREAT;
}
free(list);
return status;
}
/*
* Input list size, allocate array, and read in list.
*/
double *read_list(size_t *size_ptr, const char filename[])
{
size_t c;
double *list = NULL;
FILE *input_file;
/*
* If open fails, just return an error code to the caller. This is a
* general-purpose function, usable in many programs, so it should not
* take any specific action.
*/
input_file = fopen(filename, "r");
if ( input_file != NULL )
{
fscanf(input_file, "%zu", size_ptr); // No & here, since size_ptr is a pointer
list = (double *)malloc(*size_ptr * sizeof(*list));
for (c = 0; c < *size_ptr; ++c)
fscanf(input_file, "%lf", &list[c]);
}
fclose(input_file);
return list;
}
/*
* Print contents of a list to a file.
*/
int print_list(const double list[], size_t list_size, const char filename[])
{
size_t c;
FILE *output_file;
/*
* If open fails, just return an error code to the caller. This is a
* general-purpose function, usable in many programs, so it should not
* take any specific action.
*/
output_file = fopen(filename, "w");
if ( output_file != NULL )
{
for (c = 0; c < list_size; ++c)
fprintf(output_file, "%f\n", list[c]);
return EX_OK;
}
fclose(output_file);
return EX_CANTCREAT;
}
/*
* Sort list using selection sort algorithm.
*/
void sort_list(double list[], size_t list_size)
{
size_t start,
low,
c;
double temp;
for (start = 0; start < list_size - 1; ++start)
{
/* Find lowest element */
low = start;
for (c = start + 1; c < list_size; ++c)
if ( list[c] < list[low] )
low = c;
/* Swap first and lowest */
temp = list[start];
list[start] = list[low];
list[low] = temp;
}
}
void usage(void)
{
fputs("Usage: selsort-files input-file output-file\n", stderr);
exit(EX_USAGE);
}
4
5.4
4.1
3.9
2.7