0

I have a bunch of strings that look like:

'Hello1-FOO', 'Aello2-FOO', 'Bye1-BAR', 'Bye3-BAR', 'Hello22-FOO', 'Bye4-BAR', 'Welcome-BAR' ...

All of them are stored on a struct.

struct str {
    char *strings;
}
...
struct str **t_str;
size_t j;
t_str = malloc(sizeof *t_str * 20);
for (j = 0; j < 20; j++)
    t_str[j] = malloc(sizeof *t_str[j]);
...
t_str[0]->strings = "Hello1-FOO";
t_str[1]->strings = "Aello2-FOO";
....

What I would like to do is to display (sort) them by category, so they look similar to this:

FOO:
 Hello1-FOO
 Aello2-FOO
 Hello22-FOO

BAR:
 Bye4-BAR
 Welcome-BAR
 Bye1-BAR
 Bye3-BAR

Basically group them by the token after the '-'

What would be a good way of doing this? Should I store them on a second struct after processing the string? Any idea will be appreciated. Thanks

4
  • 1
    The first thing to fix is that your struct allows for only one string. If that's the real code, you haven't gotten far enough to have this problem yet. Commented Aug 4, 2010 at 15:08
  • @David Thornley: I have already allocated memory for all the strings mentioned above. I can display them (ungrouped) without problem. I just wanted to comment where they being held. Commented Aug 4, 2010 at 15:14
  • So do you have one str instance for each string? That's what your code looks like, but the description made it sound like you wanted to store all the strings in a single str instance Commented Aug 4, 2010 at 15:23
  • @Michael Mrozek: Sorry for the wrong description. Yes I have one str instance for each string. Commented Aug 4, 2010 at 15:27

2 Answers 2

1

Just use qsort. The following code makes some assumptions but you should be able to change it to suit your needs.

int categoryComparitor(const void * a, const void * b)
{
  char *string1 = (char *)a;
  char *string2 = (char *)b;

  string1 = strrchr(string1, '-') + 1;
  string2 = strrchr(string2, '-') + 1;

  return strcmp(string1, string2);
}


{
  ...
  char *strings[];  // Array of string pointers
  int stringCount;  // Holds current number of valid elements in strings.
  ...
  qsort(strings, stringCount, sizeof(char *), categoryComparitor);
}
Sign up to request clarification or add additional context in comments.

1 Comment

+1 for using standard libary functions instead of reinventing.
0

As David Thornley already pointed out, your struct isn't really defined well to handle this situation (well at all). Since your input is two separate logical pieces, you really want to define the struct accordingly -- containing two separate strings, one for each part of the input.

struct record { 
    char *category;
    char *string;
};

Then you want to read each piece into one of those two strings:

record read_line(FILE *infile) { 
    char buffer1[128], buffer2[128];
    fscanf(infile, "%[^-]-%s", buffer1, buffer2);
    record ret;
    ret.string = dupe_string(buffer1);
    ret.category = dupe_string(buffer2);
    return ret;
}

Then, to sort those records, you'll want to define a comparison function with the signature expected by qsort, that does a comparison on the category member:

int cmp(void *a, void *b) { 
    return strcmp(((record *)a)->category, ((record *)b)->category);
}

Then you'll sort your array of records using that comparison function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.