tags:

views:

134

answers:

5

I am trying to alphabetically sort the elements of argv.

The following line of code is giving me problems:

qsort(argv[optind], argc - optind, sizeof(argv[optind]), sort);

Specifically, the last argument is giving me trouble, the comparison function, which is given below:

int
sort(const void *a, const void * b)
{    
    return(strcmp( (char*)a, (char*)b ));
}

At the moment, it compiles fine, but I end up getting a segmentation fault when I run it.

A: 

problem is with the sort function This link will help u

Raghuram
+3  A: 

The first argument should be argv+optind, as this is the address of the first element in the sequence to be sorted.

zvrba
Really? Keep in mind that argv is an array or string pointers, so argv[optind] would be pointing to the first string.
Sjoerd
clacke
Indeed, and then the sort function needs to compare `char **`.
Sjoerd
Yes. Both things are covered by the man page for `qsort()` on http://linux.die.net/man/3/qsort .
clacke
A: 

The problem is in the structure of the argv array.

It is structured like this

program\0arg1\0argument2\0a3\0\0

The qsort function assumes that all elements are the same size, but in this case they are not. You specify the size of argv[optind], but not all elements are that size.

Edit: I was mistaken, you do not pass the string length to qsort, but the length of the pointers. So argv contains an array of pointers. The goal is to sort the pointers.

That means that you pass the array of pointers to qsort, and that the sort function should expect a pointer. Like this:

int
sort(const void *a, const void * b)
{
    return(strcmp( *(char**)a, *(char**)b ));
}

qsort(argv+optind, argc - optind, sizeof(argv[optind]), sort);
Sjoerd
So does that mean there is no way to sort the elements of argv?
DemonicImpact
This answer is incorrect. `argv` is an array of pointers. If the string data pointed to by those pointers happens to be structured as in your answer, it's purely an implementation detail of the OS/compiler **you** are using. `argv` should never be accessed as such.
R..
+2  A: 

The man page for qsort(3) contains one example, which does exactly what you want. It also explains why:

http://linux.die.net/man/3/qsort

Summary: You are missing one level of referencing on the qsort() first argument, and missing one level of dereferencing inside the sort() function.

clacke
A: 

Here's my attempt at sorting argv

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int mycomp(const void *a, const void *b) {
  /* function code removed to prevent homework copy/paste */
}

int main(int argc, char **argv) {
  int i;
  qsort(argv + 1, argc - 1, sizeof *argv, mycomp);
  for (i = 1; i < argc; i++) printf("i: %d ==> '%s'\n", i, argv[i]);
  return 0;
}

And a sample run of the program

$ ./a.out one two three four five six seven
i: 1 ==> 'five'
i: 2 ==> 'four'
i: 3 ==> 'one'
i: 4 ==> 'seven'
i: 5 ==> 'six'
i: 6 ==> 'three'
i: 7 ==> 'two'
pmg