Thread: qsort() w/ pointer swapping

  1. #1
    Registered User
    Join Date
    Dec 2003
    Location
    Fremont, CA
    Posts
    9

    qsort() w/ pointer swapping

    i'm supposed to prompt the user for the size of the array (number of strings, M) and allocate memory for it.
    then have the user input strings assigning each one an integer from 1 to M.
    my TA said that we basically have to compare the individual strings, but only swap the integers 1 through M in another array, so that in the end, i can print out the original array of strings, and then print out the sorted strings using the pointers from the other array.
    and then i have to free up the memory again to reiterate the program.

    i have the basic structure of the program w/o using the 2nd array of pointers.

    the teacher wants us to use a structure like this:

    Code:
    typedef struct {
        char * name;
        int      data;
    } Data, *pData;
    and the array of data should be declared like this:

    Code:
    pData * pArray;
    here's what i have so far...

    Code:
    #include <stdio.h>
    
    typedef struct {
    	char * name;
    	int data;
    } Data, *pData;
    
    pData pArray;
    char s[100];
    
    int main(void) {
    	int M, i, j, l;
    
    	printf("Size of array?\n->");
    	scanf("%d",&M);
    
    	pArray = (pData)malloc((M),sizeof(Data));
    	double a[M];
    
    	for (i = l, i < M, i++) {
    		printf("Enter string #%d: ", i);
    		s = gets();
    		l = strlen(s);
    		pArray[i].name = (char *)malloc(char l+i);
    		strncpy(pArray[i].name, s);
    		pArray[i].data = i;
    	}
    
    	qsort(a, M, sizeof(int), cmp);
    
        for (j = 0; j < M; j++)
            printf("\t%s\n", a[i].name);
    
        exit(0);
    }
    
    int cmp(const void *Vp, const void *Vq)
    {
    	int i, j;
    	i = (int) *Vp;
    	j = (int) *Vq;
    	strcmp(pArray[i].name, pArray[j].name);
    }

  2. #2
    Registered User
    Join Date
    Dec 2003
    Location
    Fremont, CA
    Posts
    9
    it's basically like this program, but i need to use the structure defined and have the user input the strings...

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define NUM_ENTRIES(c)  (sizeof(c)/sizeof(c[0]))
    
    char test[][20] = {"hello","world","how","are","you"};
    
    typedef char foo[20];
    
    int compare ( const void *a, const void *b ) {
        const foo *pa = a;
        const foo *pb = b;
        return strcmp( *pa, *pb );
    }
    
    int main ( ) {
        int i, num = NUM_ENTRIES(test);
        printf( "     Before\n" );
        for ( i = 0 ; i < num ; i++ ) printf( "%s\n", test[i] );
        qsort( test, num, sizeof(test[0]), compare );
        printf( "\n     After\n" );
        for ( i = 0 ; i < num ; i++ ) printf( "%s\n", test[i] );
        return 0;
    }
    taken from here
    Last edited by soopah256; 12-03-2003 at 03:21 PM.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    So what's the problem then?

    All the magic you need to worry about is in these two lines
    Code:
    char test[][20] = {"hello","world","how","are","you"};
    typedef char foo[20];
    Once you've decided what type your array is, then you can define the 'typedef foo' to match that and you're all set.

    All you need then do is write your compare() function to compare elements with whatever sort order you want to achieve.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Dec 2003
    Location
    Fremont, CA
    Posts
    9
    i'm not sure how to use compare() to compare the pArray[x].name structs...hopefully that makes sense

    and i'm also having trouble doing the allocation...
    the way my TA told me doesn't seem to work out.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    I just realised, your original code is hopeless
    It won't even compile, and it uses some C++ features.
    Man, if you're getting a load of warnings you're ignoring, then I'd take a big step back.

    Code:
    // include stdlib.h and stop casting the result of malloc
    // malloc takes 1 parameter, not 2
    // suggest pArray = malloc ( M * sizeof *pArray );
    	pArray = (pData)malloc((M),sizeof(Data));
    
    // this is C++ (or C99) only 
    // C89 does not permit variable length arrays
    	double a[M];
    
    // Duh, l is uninitialised.
    // Saying 1 doesn't help as arrays start at 0
    // for ( i = 0 ; i < M ; i++
    	for (i = l, i < M, i++) {
    		printf("Enter string #%d: ", i);
    // go read the FAQ
    // gets() is horrible, and you're using it wrong anyway
    		s = gets();
    		l = strlen(s);
    		pArray[i].name = (char *)malloc(char l+i);
    // just use strcpy() here - you know the length is
    // ok, and you need the \0 anyway
    		strncpy(pArray[i].name, s);
    		pArray[i].data = i;
    	}
    
    // lying to qsort about the size of elements of the array
    // try sizeof(Data) not sizeof(int)
    	qsort(a, M, sizeof(int), cmp);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Dec 2003
    Location
    Fremont, CA
    Posts
    9
    first, i'd just like to say thanks for all your help, Salem!

    yeah, i'm trying to do the assignment according to the handout
    Use the function qsort to sort an array of pointer to structure whose primary key is a string.

    Create a program to test this.
    The structure shall be defined like this:
    Code:
    typedef struct {
         char * name;
         int    data;
    } Data, *pData;
    Your user interface shall prompt the user for the size of the array, M. The program shall dynamically allocate an array of structure (Data) of size M. It shall then prompt the user for each string and randomly generate each integer in the range 1 to M. Use gets to fetch the string (an entire line). Your program shall then dynamically allocate each array of char and use strcpy to copy the string read from the user. Your program should print out the initial array contents in a pleasing format, call qsort, and then print out the results.

    The compare function can use strcmp to compare the individual strings.

    The array of data shall be declared like this:
    Code:
    pData * pArray;
    When your program finishes, or if the program iterates and reallocates a new array, make sure it frees any memory that it had previously allocated.
    so i'm trying to find some middleground of the proper way to do this, and the way i'm told to do it...

  7. #7
    Registered User
    Join Date
    Dec 2003
    Location
    Fremont, CA
    Posts
    9
    can someone show me how i can use the gets() function along with the strcpy() function? i can't figure out how to use both of them trying to do the same thing

  8. #8
    Registered User linuxdude's Avatar
    Join Date
    Mar 2003
    Location
    Louisiana
    Posts
    926
    strcpy's prototype is

    Code:
    char *strcpy(char *dest, const char *src);
    where *src is copied to *dest until the '\0' is reached

    gets()'s prototype is

    Code:
    char *gets(char *s);
    get's input from stdin until the '\n' character is reached or the EOF macro

  9. #9
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by soopah256
    can someone show me how i can use the gets() function along with the strcpy() function? i can't figure out how to use both of them trying to do the same thing
    Get your input via gets() (please check this link first) into a temporary buffer.

    Then use strcpy() to copy the string to the buffer where you want the string to finally reside.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  10. #10
    Registered User
    Join Date
    Dec 2003
    Location
    Fremont, CA
    Posts
    9
    Originally posted by WaltP
    Get your input via gets() (please check this link first) into a temporary buffer.

    Then use strcpy() to copy the string to the buffer where you want the string to finally reside.
    thanks waltp! i found that in my book. i hate this. my teacher tells me to do everything the wrong way...

    i really don't want to ask, and i know that it's against forum rules ....but i need to finish this lab by tomorrow. does someone think they could help me fix what's wrong with my lab. i don't think i can figure out how to work it with my teacher's specifications. i guess i really just need memory allocation and pointer swapping...

    thank you everybody so much for helping me with this!

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    Like so
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
      char *name;
      int   data;
    } Data;
    
    int cmp(const void *Vp, const void *Vq);
    
    int main(void) {
      char buff[BUFSIZ];
      Data   *pArray;
      int     M, i, j;
      size_t  l;
    
      printf("Size of array?\n->");
      fgets( buff, sizeof buff, stdin );
      sscanf( buff, "%d", &M );
      pArray = malloc( M * sizeof *pArray );
    
      for ( i = 0; i < M; i++) {
        printf("Enter string #%d: ", i);
        fgets( buff, sizeof buff, stdin );
        l = strlen(buff);
        buff[l-1] = '\0';     /* remove the newline */
        pArray[i].name = malloc(l+1);
        strcpy(pArray[i].name, buff);
        pArray[i].data = i;
      }
    
      for (j = 0; j < M; j++)
        printf("\t%d\t%s\n", pArray[j].data, pArray[j].name);
      qsort(pArray, M, sizeof(*pArray), cmp);
      for (j = 0; j < M; j++)
        printf("\t%d\t%s\n", pArray[j].data, pArray[j].name);
    
      return 0;
    }
    
    int cmp(const void *Vp, const void *Vq)
    {
      const Data *p = Vp;
      const Data *q = Vq;
      return strcmp(p->name, q->name);
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  2. How did you master pointers?
    By Afrinux in forum C Programming
    Replies: 15
    Last Post: 01-17-2006, 08:23 PM
  3. scope of a pointer?
    By Syneris in forum C++ Programming
    Replies: 6
    Last Post: 12-29-2005, 09:40 PM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. Could somebody please help me with this C program
    By brett73 in forum C Programming
    Replies: 6
    Last Post: 11-25-2004, 02:19 AM