Domanda

Secondo questo sito

http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/

Ho fatto seguente programma che ordina le stringhe

#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char list[5][4]={"dat","mai","lik","mar","ana"};
int main(int argc, char *argv[])
{
    int x;
    puts("sortirebamde:");
     for (x=0;x>sizeof(list)/sizeof(char);x++)
     printf("%s\n",list[x]);
      qsort(&list,(sizeof(list)/sizeof(char)),sizeof(list[0]),strcmp);
    system("PAUSE");
    return EXIT_SUCCESS;
}

Ecco l'errore che ottengo

13 C:\Documents and Settings\LIBRARY\Desktop\string_sortireba.cpp invalid conversion from `int (*)(const char*, const char*)' to `int (*)(const void*, const void*)' 
13 C:\Documents and Settings\LIBRARY\Desktop\string_sortireba.cpp   initializing argument 4 of `void qsort(void*, size_t, size_t, int (*)(const void*, const void*))' 

Si prega di aiuto

È stato utile?

Soluzione

Si prega di notare: Non è facile memorizzare le stringhe C in due array di caratteri dimensionali. E 'più normale avere char *ary[], come ad esempio argv. Questo tipo non può essere risolto direttamente utilizzando qsort e strcmp, perché qsort passerà char ** non char * alla funzione di confronto. Questo è un bene per l'efficienza, i puntatori possono essere scambiati al posto di tutto stringhe. Il Linux pagina di manuale per qsort ha qualche codice buon esempio con una funzione di confronto corretto.

Non è possibile passare direttamente alla strcmp qsort come la sua funzione di confronto, perché si aspetta qsort di passare puntatori a vuoto dove strcmp aspetta puntatori a const char. Data la somiglianza richiesta tra puntatori a vuoto e puntatori a char, potrebbe , probabilmente farlo con un cast (per il codice), ma il modo più pulito sarebbe quello di scrivere una funzione che prende i giusti tipi:

int cmpstr(void const *a, void const *b) { 
    char const *aa = (char const *)a;
    char const *bb = (char const *)b;

    return strcmp(aa, bb);
}

Si noti, tuttavia, che in C ++ che normalmente si desidera utilizzare std::sort invece di qsort, e probabilmente usare std::string invece di char *, qual caso l'ordinamento diventa molto più semplice (e generalmente più veloce pure).

Altri suggerimenti

Il quarto argomento di qsort prende 2 puntatori void * come args.So è necessario definire una funzione di confronto per il vostro. fare riferimento a questo link per ulteriori dettagli.

Al di là perché qsort fallisce , non utilizzare in C ++.

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

char const* const raw_data[5] = {"dat", "mai", "lik", "mar", "ana"};

std::vector<std::string> data (raw_data, raw_data + 5);
// would rarely be a global

// see below for code that needs to go here

int main() {
  using namespace std;
  cout << "before: " << data << "\n";
  sort(data.begin(), data.end());
  cout << "after: " << data << "\n";
  return 0;
}

Boost ha flusso di inserimento sovraccarichi di uscita un vettore direttamente, ma qui è una versione semplice . Questo va in un colpo di testa, piuttosto che essere copiato e incollato in continua:

template<class Stream, class Iter, class Ch>
void write_sequence(Stream& s, Iter begin, Iter end, Ch const* initial, Ch const* sep, Ch const* final) {
  if (initial) {
    s << initial;
  }
  if (begin != end) {
    s << *begin;
    ++begin;
    for (; begin != end; ++begin) {
      if (sep) {
        s << sep;
      }
      s << *begin;
    }
  }
  if (final) {
    s << final;
  }
}

template<class T, class A>
std::ostream& operator<<(std::ostream& s, std::vector<T,A> const& value) {
  write_sequence(s, value.begin(), value.end(), "[", ", ", "]");
  return s;
}

È possibile passare direttamente a strcmp qsort

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char list[5][4]={"dat","mai","lik","mar","ana"};
int main(int argc, char *argv[]) {
    int x;
    puts("unsorted:");
    for (x=0;x<sizeof(list)/sizeof(list[0]);x++)
        printf("%s\n",list[x]);

    qsort(list,sizeof(list)/sizeof(list[0]),sizeof(list[0]),strcmp);

    puts("sorted:");
    for (x=0;x<sizeof(list)/sizeof(list[0]);x++)
        printf("%s\n",list[x]);
//  system("PAUSE");
    return EXIT_SUCCESS;
}

uso C, C ++ non

Maggiori C ++ - Style - al giorno d'oggi - con static_cast:

int scmp(const void * s1, const void * s2)
{
    const char* _s1 = *static_cast<const char* const*>(s1);
    const char* _s2 = *static_cast<const char* const*>(s2);
    return strcmp(_s1, _s2);
}

E nel main ():

char *str_arr[] = { "one", "two", "three" };
qsort(str_arr, sizeof(str_array)/sizeof(char*), sizeof(char*), scmp);

Molto più facile è con vettore e std :: sort.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top