Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 19
  1. #1
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479

    [C] Usare qsort con strcmp

    Ciao a tutti, vorrei utilizzare la funzione qsort con la funzione strcmp, ho scritto il seguente programma:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main( int argc, char** argv )
    {
    	qsort( argv, argc, sizeof(char*), strcmp );
    	
    	int i;
    	for( i = 1; i < argc; i++)
    		printf("%s\n", *(argv+i) );
    	
    	return 1;
    }
    Soltanto che mi da un warning proprio sulla funzione qsort dicendomi:

    passing arg 4 of qsort from incompatible pointer type, qualcuno saprebbe aiutarmi?

    Grazie
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Non puoi usare direttamente la strcmp perche' i parametri della funzione che la qsort si attende devono essere const void *.

    Puoi scrivere una funzione che "incapsuli" la strcmp presentandosi correttamente alla qsort ... una funzione che puoi chiamare strcmp2

    codice:
    int strcmp2(const void *s1, const void *s2)	
    {
       return strcmp(*(char **)s1, *(char **)s2);
    }
    
    int main( int argc, char** argv )
    {
       qsort( argv+1, argc-1, sizeof(char*), strcmp2);
    	
       int i;
       for( i = 1; i < argc; i++)
          printf("%s\n", *(argv+i) );
    	
       return 0;
    }
    Attenzione ai primi due argomenti della qsort dato che devi evitare di includere nell'ordinamento anche il primo elemento del vettore argv (che e' il nome dell'eseguibile ...).

    Ho anche corretto l'ultimo valore restituito dal main, ma solamente perche', in genere, un valore diverso da zero indica al chiamante una condizione di errore.

  3. #3
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Ah ho capito e se invece di mettere
    codice:
    int strcmp2(const void *s1, const void *s2)	
    {
       return strcmp(*(char **)s1, *(char **)s2);
    }
    mettessi

    codice:
    int strcmp2(const void *s1, const void *s2)	
    {
       return strcmp(s1, s2 );
    }
    che cosa cambierebbe? Non ho ben capito la deferenziazione delle due stringhe s1 ed s2 e il cast ad array di stringhe con (char**).. potresti dirmi il motivo?

    Grazie
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Non avrebbe funzionato ...

    Alla funzione di callback della qsort i parametri passati sono puntatori a due elementi da confrontare. Nel caso di due stringhe, vengono passati due puntatori a puntatori a carattere.
    Ecco il motivo del cast

    (char **)s1

    Ma la strcmp opera su puntatori a caratteri e quindi

    (*(char **)s1)

  5. #5
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Hem, sto cercando di usare questa qsort ma mi da un sacco di problemi, io ho una struct cosi' definita:

    codice:
    struct Carta
    {
    	char seme;
    	int tipo;
    };
    Ho fatto due funzioni una per creare un mazzo ( struct Carta **mazzo ) e una per mescolare il mazzo. Adesso vorrei fare una funzione per mi consenta di rimettere il mazzo nella posizione originale cioe' ordinato da 1 a K e cuori-picche-fiori-mattoni.

    Intanto volevo provare soltanto con le cuori e ho scritto il criterio di confronto cosi'
    codice:
    int compare( const void *s1, const void *s2 )
    {
    	struct Carta *first = (struct Carta*) s1;
    	struct Carta *second =  (struct Carta*) s2;
    	
    	if( first->seme == 'c' && second->seme == 'c' )
    	{
    		if( first->tipo > second->tipo )
    			return 1;
    		else if ( first->tipo < second->tipo )
    			return -1;
    		else
    			return 0;
    	}
    			
    }
    ed
    codice:
    void ordinaMazzo( struct Carta **mazzo )
    {
    	qsort( mazzo, 52, sizeof( struct Carta* ), compare );
    }

    pero' non funziona, c'e' qualche errore di concetto ?
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Intanto cominciamo dai "mattoni" ... ma che sono?

    Io ho sempre saputo che i semi sono cuori-quadri-fiori-picche ... e uno che si chiama Poker dovrebbe saperlo ...

    A parte questo, ci sono un po' di errori logici ...

    Intanto nella definizione della struttura che rifarei cosi'

    codice:
    struct Carta
    {
      char seme;
      char valore;
    };
    in modo che i nomi dei campi siano chiari. In piu' li definirei ambedue di tipo char ma trattandoli come valori numerici.
    Ovvero, il valore seme puo' essere

    0 = cuori
    1 = quadri
    2 = fiori
    3 = picche

    e il valore da 1 (A) a 13 (K)

    Quando si trattera' di dover stampare il seme, scriverai il codice opportuno per la conversione.

    Fatto questo, il problema fondamentale e' capire che l'elemento che tu vuoi ordinare e' di tipo

    struct Carta

    e di questo elemento va calcolata la grandezza e passata nella qsort cosi'

    codice:
    qsort( mazzo, 52, sizeof(struct Carta), compare );
    e non passando il tipo puntatore a struttura come hai fatto.
    Nell'esempio precedente, quando erano gli elementi erano delle stringhe, si lavorava sul loro tipo, ovvero puntatore a carattere che si inseriva nella qsort ... non ti confondere.

    Detto cio', la compare, dato che adesso compaiono soltanto elementi numerici, diventa

    codice:
    int compare( const void *s1, const void *s2 )
    {
      struct Carta *first = (struct Carta*) s1;
      struct Carta *second =  (struct Carta*) s2;
    	
      if(first->seme != second->seme)
        return(first->seme - second->seme);
    
      return(first->valore - second->valore);
    }
    e mi sembra molto chiara.

  7. #7
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Ok, adesso provo a modificare il codice.

    P.S: in toscana i quadri li chiamiamo mattoni :-)
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  8. #8
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Ho fatto le modifiche ma con la comp come mi hai suggerito mi da un Segmentation fault..bho ora vedo se riesco a risolvere
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Posta il codice completo ... cosi' vedo se hai dimenticato qualcosa ...

    (Usi linux/gcc ?)

  10. #10
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Si uso Linux/gcc.

    Allora, ho modificato le seguenti cose:

    ASPETTA CHE FORSE HO RISOLTO

    codice:
    int compare( const void *s1, const void *s2 )
    {
    	struct Carta *first = (struct Carta*) s1;
    	struct Carta *second = (struct Carta*) s2;
    	
    	if(first->seme != second->seme)
        	   return(first->seme - second->seme);
        	return(first->valore - second->valore);		
    }
    
    void ordinaMazzo( struct Carta **mazzo )
    {
    	qsort( mazzo, 52, sizeof( struct Carta ), compare );
    }
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.