I had a silly assignment:
You are given a binary file FLOATS.DAT of unknown length, type
float
data has been written in it. Write a program which sorts the data in the file (the output is a sorted file FLOATS.DAT). You need to sort it without loading the file into memory, or by using a temporary file. Use the Shell sort algorithm.
Obviously by using a temp. file it would be easy, even more if you could load it into memory.
Here is my solution:
#include <stdio.h>
// sizeof(float) = 4 on my machine
int main(int argc, char **argv)
{
size_t sajz = sizeof(float); // for convenience
int n; // total number of floats in the file
FILE *dat;
dat = fopen("FLOATS.DAT", "r+b");
if (dat == NULL)
{
printf("Error while opening.\n");
return 1;
}
// find the number of floats in the file
fseek(dat, 0, SEEK_END);
n = ftell(dat)/sajz;
rewind(dat);
float tjmh, tx;
int i,j,h;
// standard shell sort algorithm, the hard part is when I have to
// read a position I first have to jump to it, then read it,
// same when writing to a location
for (h = n/2; h>0; h/=2)
{
for (i=h; i<n; i++)
{
j = i;
fseek(dat, i*sajz, SEEK_SET);
fread(&tx, sajz, 1, dat);
rewind(dat);
fseek(dat, (j-h)*sajz, SEEK_SET);
fread(&tjmh, sajz, 1, dat);
rewind(dat);
for (; j>=h && tx < tjmh; j -= h)
{
fseek(dat, j*sajz, SEEK_SET);
fwrite(&tjmh, sajz, 1, dat);
rewind(dat);
// this was tricky to figure out
// I need the value of `j` after it has been
// subtracted from h
fseek(dat, (j - 2*h)*sajz, SEEK_SET);
fread(&tjmh, sajz, 1, dat);
rewind(dat);
}
fseek(dat, j*sajz, SEEK_SET);
fwrite(&tx, sajz, 1, dat);
rewind(dat);
}
}
fclose(dat);
return 0;
}
Can this be improved in any way?
Code snippet to generate the file with numbers 2.0, 3.0, 10.0, 4.0, 1.0, 7.0, 9.0, 5.0, 6.0, 8.0
int main()
{
FILE *dat;
dat = fopen("FLOATS.DAT", "wb");
float a;
if (dat)
{
a = 2.00;
fwrite(&a, sizeof(float), 1, dat);
a = 3.00;
fwrite(&a, sizeof(float), 1, dat);
a = 10.00;
fwrite(&a, sizeof(float), 1, dat);
a = 4.00;
fwrite(&a, sizeof(float), 1, dat);
a = 1.00;
fwrite(&a, sizeof(float), 1, dat);
a = 7.00;
fwrite(&a, sizeof(float), 1, dat);
a = 9.00;
fwrite(&a, sizeof(float), 1, dat);
a = 5.00;
fwrite(&a, sizeof(float), 1, dat);
a = 6.00;
fwrite(&a, sizeof(float), 1, dat);
a = 8.00;
fwrite(&a, sizeof(float), 1, dat);
fclose(dat);
}
return 0;
}
You can use an array here as well.
mmap()
be considered "loading the file into memory"? \$\endgroup\$float
data", one first has to determine whether it's possible to unambiguously determine the non-portable bit representation that was used to write it, otherwise it's of no use... and even if you can figure that out, your system might differ, meaning you'd have to convert to its representation, which isn't necessarily trivial. All of which supports your conclusion that - like so many others - it's a "silly assignment". ;) \$\endgroup\$net2HostIEEE()
andhost2NetIEEE()
\$\endgroup\$