--> Paul Druggitt wrote to Cliff Rhodes <--
PD> This if(....) checks each byte for equality, which doesn't quite
PD>solve my problem, which is I wish see which is the lowest value.
Yep, I just wanted to show you how to do that. I figured you might get
some ideas from that and go from there.
PD> 1) How can I check properly which is REALLY the lowest value?
PD> whether it be int, long, double, string etc.....
PD> Do I somehow have to convert the 4 bytes that represent a long
PD> into a proper long value etc? If so, how?
There are a number of alternatives. You could pass a compare function
to the routine that worked on the correct types--just like the library
function qsort(). Or, you could pass a value indicating the type and
use a switch statement to perform the correct comparison.
Here's the code with some modifications:
#include
#include
#include
/* Enum to identify the types of arguments that might be compared */
typedef enum { Int, Long, String } dType;
static int Icmp(const void *a, const void *b)
{
/* Routine to compare two ints pointed to by a and b */
if(*(int *)a > *(int *)b)
return 1;
else if(*(int *)a < *(int *)b)
return -1;
return 0;
}
static int Lcmp(const void *a, const void *b)
{
/* Routine to compare two longs pointed to by a and b */
if(*(long *)a > *(long *)b)
return 1;
else if(*(long *)a < *(long *)b)
return -1;
return 0;
}
static int Scmp(const void *a, const void *b)
{
/* Routine to compare two strings pointed to by a and b */
return strcmp(a, b);
}
/* Array of pointers to compare functions for the types */
static int (*fcmp[3])(const void *, const void *) =
{ Icmp, Lcmp, Scmp };
int membercmp(void *struc, size_t ssize, void *data, dType d, FILE
*fp)
{
/* Given a pointer to some structure struc, and the size of
* that type of structure, ssize, compare the member pointed
* to by data of type d in struc and the next record
* read from file fp. Returns 0 if the members are equal, 1 if
* the record read is larger than *data, or -1 if smaller.
*/
int i, ret = 0;
/* Get the offset of the data member in struc... */
size_t doffset = (char *) data - (char *) struc;
char *s = malloc(ssize); /* Get space to save record */
fread(s, ssize, 1, fp); /* Read the record */
/* Do the compare by calling the correct function using dType d */
ret = fcmp[d](s + doffset, data);
free(s); /* Free the allocated space */
return ret;
}
/* Routine to show how the function is called */
int main(void)
{
FILE *fp;
int i;
struct { int i, j; long date, k; } DATA;
DATA.i = 1;
DATA.j = 2;
DATA.date = 66000L;
DATA.k = 23L;
fp = fopen("STRUCT.DAT", "wb");
fwrite(&DATA, sizeof(DATA), 1, fp);
fclose(fp);
fp = fopen("STRUCT.DAT", "rb");
i = membercmp(&DATA, sizeof(DATA), &DATA.date, Long, fp);
if(i < 0)
puts("File date smaller");
else if(i > 0)
puts("File date larger");
else
puts("Dates are the same");
fclose(fp);
return 0;
}
PD> 2) Once I know which is the lowest value, how do I set the prev &
PD> next values in the record I wish to write to the file, likewise
PD> the records already in the file that I need to alter the prev &
PD> next values, bearing in mind that within this function we are
PD> dealing with a void pointer to my structure DATA.
PD>
PD> 3) Is there an easier way to add records to a file, sorted in the
PD> order I specify(date order, alphabetic order etc...), without
PD> having to rewrite the whole file. I am trying to do it as a
PD> linked list FILE at present.
If you change the order, you will in effect have to rewrite the entire
file. There just isn't any way around this, since all the prev and
next positions will need to be updated.
Can you fit your entire data file into memory? That will make things a
lot easier. Just read in the entire file, do your sorting in memory,
then write out the whole thing.
PD> CR> membercmp(&DATA, sizeof(DATA), &DATA.date, sizeof(DATA.date),
PD> CR> fp1);
PD>
PD> Would I also need to pass the addresses of DATA.prev & DATA.next
PD>to the function?
Paul, you are giving me a moving target here! First you just wanted to
compare members in different size records, now you want to do a
sorting routine.
Why don't you write a message spelling out exactly what you are trying
to accomplish--the big picture. I think there is probably a much
easier way to tackle this design, but I can't recommend anything
without knowing precisely what you are after.
Cliff Rhodes
cliff.rhodes@juge.com
X CMPQwk 1.42 1692 X"He knows peace who has forgotten desire." - Bhaga
--- Maximus/2 3.01
---------------
* Origin: COMM Port OS/2 juge.com 204.89.247.1 (281) 980-9671 (1:106/2000)
|