Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

C Qsort źle sortuje

Ostatnio zmodyfikowano 2013-04-08 01:08
Autor Wiadomość
Nazor
Temat założony przez niniejszego użytkownika
C Qsort źle sortuje
» 2013-04-08 00:26:00
Rekreacyjne zadanie posortować w C bazę 10.000 osób. Pobrać z pliku baza_danych.txt dane. Są one w formacie:
Imie Nazwisko Pensja
posortować po nazwisku. Prostym bubble sortem poszło bez problemu ale chciałem sobie sprawdzić qsorta.
Np. input:
Radek Biemczyk 1000
Wiktor AaaaTraktor 22
Jurek Cgorek 200
Karol Wojtyla 55
Grzegorz Dostyla 666
Carl Edmont 75
Fred Fredra 80
Greg Gregory 66
Howard Hui 88
Ilena Ile 55

Jest ktoś w stanie mi wytłumaczyć czemu ten qsort nie chce posortować poprawnie?

C/C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<time.h>
#define ROZM 10000


struct osoba {
    char imie[ 20 ];
    char nazwisko[ 20 ];
    int zarobki;
};

struct osoba * wykaz[ ROZM ];
int ilosc; // ilosc zapisow w tablicy "wykaz"
FILE * plikBazy;

void czytaj() {
    //czytanie danych z pliku "wykaz.txt" do tablicy "wykaz"
    int i = 0;
    struct osoba o;
    plikBazy = fopen( "baza_danych.txt", "r" );
    if( plikBazy == NULL ) {
        printf( "blad odczytu" );
        return;
    }
    while( i < ROZM && fscanf( plikBazy, "%s%s%d", o.imie, o.nazwisko, & o.zarobki ) != EOF ) {
        wykaz[ i ] =( struct osoba * ) malloc( sizeof( struct osoba ) );
        strcpy( wykaz[ i ]->imie, o.imie );
        strcpy( wykaz[ i ]->nazwisko, o.nazwisko );
        wykaz[ i ]->zarobki = o.zarobki;
        i++;
    }
    ilosc = i;
    printf( "przeczytano %d zapisow\n", ilosc );
}

void drukuj() {
    struct osoba o;
    int i = 0;
    while( i < ilosc ) {
        strcpy( o.imie, wykaz[ i ]->imie );
        strcpy( o.nazwisko, wykaz[ i ]->nazwisko );
        o.zarobki = wykaz[ i ]->zarobki;
        printf( "%s %i\n", o.nazwisko, o.zarobki );
        i++;
    }
}

int compare2( const void * a1, const void * a2 )
{
    const struct osoba * ch1 =( const struct osoba * ) a1;
    const struct osoba * ch2 =( const struct osoba * ) a2;
    return strcmp( ch1->nazwisko, ch2->nazwisko );
    //  return strcmp(ch2->nazwisko,ch1->nazwisko);
}

void sortuj()
{
    qsort( wykaz, ROZM, sizeof( struct osoba * ), compare2 );
}

int main( void )
{
    czytaj();
    //drukuj();
    printf( "\n\n" );
    clock_t pocz = clock();
    qsort( wykaz, ilosc, sizeof( struct osoba * ), compare2 );
    clock_t koniec = clock();
    drukuj();
    printf( " \nCzas wykonania: %lf sek.\n\n",( double )( koniec - pocz ) / CLOCKS_PER_SEC );
    return ilosc;
}
P-80191
DejaVu
» 2013-04-08 00:48:28
qsort nie może sortować źle. Co najwyżej Twój kod może zawierać błędy.
P-80193
Monika90
» 2013-04-08 00:51:13
To proste, argumentami funkcji compare są wskaźniki do elementów, a u ciebie elementy to też wskaźniki, zatem są to wskaźniki do wskaźników. Poprawnie jest tak:
C/C++
int compare2( const void * a1, const void * a2 )
{
    const struct osoba * ch1 =*( const struct osoba * const * ) a1;
    const struct osoba * ch2 =*( const struct osoba * const * ) a2;
    return strcmp( ch1->nazwisko, ch2->nazwisko );
}
P-80194
Nazor
Temat założony przez niniejszego użytkownika
» 2013-04-08 00:55:30
Jestem wdzięczny ale...
Wiesz że przez Ciebie czuję się bardzo głupio?
Wielkie dzięki za pomoc. Całkowicie nie zwróciłem na to uwagi.
P-80195
DejaVu
» 2013-04-08 01:08:48
Jak zauważyłem, to Monika90 ma bardzo dużą wiedzę zarówno z języka C jak i standardu C++11. Błędy popełnia każdy z nas - po prostu trzeba nauczyć się krytycznie oceniać własną pracę, a nie szukać błędów tam gdzie ich być nie może :) W każdym razie temat zamykam, skoro został on skutecznie rozwiązany.
P-80197
« 1 »
  Strona 1 z 1