-
Hi, I've made some changes to my previous post, didn't realized you replied before I hit the submit button.
EDIT:
Sorry, further changes met but still back to square 1 of not getting sorted.
Code:
int compare(const void * p1, const void * p2)
{
const struct dataTuple *ps1 = p1;
const struct dataTuple *ps2 = p2;
int res;
res = strcmp(ps1->server, ps2->server);
if(res != 0)
return 0;
else
return strcmp(ps1->name,ps2->name);
}
Here's the code of how I store my values
Code:
Tuple *data[7];
FILE *in, *out;
char line[100];
char *tokenPtr;
const char delit[2]=",";
int counter, length, i, j=0,k;
while((fgets(line,1000,in)) != NULL)
{
counter = 0;
if((data[j] = (Tuple *)malloc(sizeof(Tuple))))
{
if(data == NULL)
{
printf("Unable to allocate memory!");
exit(1);
}
tokenPtr = strtok(line,delit);
while(tokenPtr != NULL)
{
counter++;
switch(counter)
{
case 1:
strcpy(data[j]->name,tokenPtr);
length = strlen(data[j]->name);
/* I'm trying to implement a fixed-length record so you can ignore this bit of code*/
if(length<12)
{
for(i=0;i<12;i++)
{
if(!isalpha(data[j]->name[i]) && data[j]->name[i] != '\'')
{
data[j]->name[i] = '\0';
}
}
}
break;
case 2:
strcpy(data[j]->server,tokenPtr);
length = strlen(data[j]->server);
if(length<30)
{
for(i=0;i<30;i++)
{
if(!isalpha(data[j]->server[i]))
{
data[j]->server[i] = '\0';
}
}
}
break;
}
tokenPtr = strtok(NULL,delit);
}
j++;
}
}
printf("Unsorted: \n");
for(k=0;k<=count;k++)
{
printf("Data : %s\n", data[k]->server);
}
printf("\n");
qsort(data,count,sizeof(Tuple),compare);
printf("Sorted: \n");
for(k=0;k<=count;k++)
{
printf("Data : %s\n", data[k]->server);
free(data[k]);
}
-
> const struct Tuple *ps1 = p1;
You don't have a struct called Tuple
You have a typedef, in which case it would be
const Tuple *ps1 = p1;
Or a struct
const struct dataTuple *ps1 = p1;
But if your input array is really a set of Tuple*, then these need to be say
const Tuple **ps1 = p1;
and
strcmp( (*ps1)->server, (*ps2)->server);
Don't forget the array overstep I mentioned earlier.
-
Yes, I've switched to a counter to count the number of elements instead of giving it a fixed value. That should prevent the overstep but I'm still baffled on how its not sorting at all. The codes are in my previous post
-
Post your latest complete test code.
-
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXSIZE 100
typedef struct dataTuple
{
char name[12];
char server[30];
unsigned int faction;
unsigned int race;
unsigned int class;
unsigned int lvl;
unsigned int guild;
}Tuple;
int compare(const void * p1, const void *p2);
int main(int argc, char *argv[])
{
Tuple *data[7];
FILE *in, *out;
char line[100];
char *tokenPtr;
const char delit[2]=",";
int counter, length, i, j=0,k,count=0;
if(argc != 3)
{
printf("Usage: %s filename\n", argv[0]);
exit(1);
}
if((in = fopen(argv[1], "r"))==NULL)
{
fprintf(stderr,"**>Error opening %s", argv[1]);
}
out = fopen(argv[2], "wb");
while((fgets(line,1000,in)) != NULL)
{
counter = 0;
if((data[j] = (Tuple *)malloc(sizeof(Tuple))))
{
if(data == NULL)
{
printf("Unable to allocate memory!");
exit(1);
}
tokenPtr = strtok(line,delit);
while(tokenPtr != NULL)
{
counter++;
switch(counter)
{
case 1:
strcpy(data[j]->name,tokenPtr);
length = strlen(data[j]->name);
if(length<12)
{
for(i=0;i<12;i++)
{
if(!isalpha(data[j]->name[i]) && data[j]->name[i] != '\'')
{
data[j]->name[i] = '\0';
}
}
}
break;
case 2:
strcpy(data[j]->server,tokenPtr);
length = strlen(data[j]->server);
if(length<30)
{
for(i=0;i<30;i++)
{
if(!isalpha(data[j]->server[i]))
{
data[j]->server[i] = '\0';
}
}
}
break;
case 3:
data[j]->faction = atoi(tokenPtr);
break;
case 4:
data[j]->race = atoi(tokenPtr);
break;
case 5:
data[j]->class = atoi(tokenPtr);
break;
case 6:
data[j]->lvl = atoi(tokenPtr);
break;
case 7:
data[j]->guild = atoi(tokenPtr);
break;
}
tokenPtr = strtok(NULL,delit);
}
j++;
count++;
}
}
for(k=0;k<count;k++)
{
printf("Data : %s\n", data[k]->server);
}
printf("\n");
printf("Count : %d\n", count);
qsort(data,count,sizeof(Tuple),compare);
for(k=0;k<count;k++)
{
/*fwrite(data[k],sizeof(Tuple),1,out);
*/printf("Data : %s\n", data[k]->server);
free(data[k]);
}
fclose(in);
fclose(out);
return 0;
}
int compare(const void * p1, const void * p2)
{
const struct dataTuple *ps1 = p1;
const struct dataTuple *ps2 = p2;
int res;
res = strcmp(ps1->server, ps2->server);
if(res != 0)
return 0;
else
return strcmp(ps1->name,ps2->name);
}
-
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXSIZE 100
typedef struct dataTuple
{
char name[12];
char server[30];
unsigned int faction;
unsigned int race;
unsigned int class;
unsigned int lvl;
unsigned int guild;
}Tuple;
int compare(const void * p1, const void *p2);
int main(int argc, char *argv[])
{
Tuple *data[7];
Tuple d[7] = {
{ "wilma", "bedrock" },
{ "pebbles", "stonetown" },
{ "barney", "bedrock" },
{ "bambam", "stonetown" },
{ "dino", "stonetown" },
{ "betty", "bedrock" },
{ "fred", "bedrock" },
};
int k, count = 7;
for(k=0;k<count;k++)
{
data[k] = &d[k];
printf("Data : %s %s\n", data[k]->name, data[k]->server);
}
printf("\n");
printf("Count : %d\n", count);
qsort(data,count,sizeof(Tuple*),compare);
for(k=0;k<count;k++)
{
printf("Data : %s %s\n", data[k]->name, data[k]->server);
}
return 0;
}
int compare(const void * p1, const void * p2)
{
const struct dataTuple * const *ps1 = p1;
const struct dataTuple * const *ps2 = p2;
int res;
res = strcmp( (*ps1)->server, (*ps2)->server);
if(res != 0)
return res; //!! was 0;
else
return strcmp( (*ps1)->name, (*ps2)->name);
}
$ ./a.exe
Data : wilma bedrock
Data : pebbles stonetown
Data : barney bedrock
Data : bambam stonetown
Data : dino stonetown
Data : betty bedrock
Data : fred bedrock
Count : 7
Data : barney bedrock
Data : betty bedrock
Data : fred bedrock
Data : wilma bedrock
Data : bambam stonetown
Data : dino stonetown
Data : pebbles stonetown
-
Thanks. Btw, does the address value is always a negative? I realised my problem is the pointers or so I thought. I tried printing the addresses in the compare function and in the main function, they came up with a different address. So maybe I thought it would be a pointer issue.
I tried
Code:
for(k=0;k<count;k++){
printf("Address : %d\n", &data[k]");
}
I get all negative values. Is that common?
-
The numbers are so high, that they appear negative. Print them either as unsigned integers, or in hexadecimal value.
Personally, I prefer printing memory addresses in hexadecimal. Use either %x or %X (depending if you want upper or lower case for the letters A through F) instead of %d.
-
The official format for printing a pointer is %p
-
Yes, sorry, for portability you should use %p for any pointer values, which also print in hexadecimal.