C++ / C mit qsort strings sortieren

Hallo zusammen,

bin gerade dabei ein Programm zu schreiben das Wörter (Strings)nach dem ABC sortiert.

Hier Ein Beispiel:

Eingabe: Hallo alle sind aus Zucker
Ausgabe: alle, aus, Hallo, sind, Zucker

Nun habe ich das ganze schon mit einem normalen Array in dem sich verschieden Zahlen befanden geschrieben aber mit den Strings komme ich nicht ganz zurecht.

Meine Eingabe sind wie folgt aus:

#include
#include
#include

using namespace std;

#define MAX 10

int compare( const void *a, const void *b );

void Programm_1()
{
string Eingabe[MAX];
int i=0;

cout > Eingabe[i];
i++;
}while(Eingabe[i-1] != „\0“ || i == MAX );

qsort( (void *)Eingabe, (size_t)MAX, sizeof( char * ), compare );

for (i=1; i

Howdy,

lies und versteh das folgende Beispiel:

#include 
#include 

#include 
#include 

typedef std::vector vector\_t;

class MyVector : public vector\_t
{
public:
 MyVector()
 : vector\_t()
 {
 reserve(32);
 }

 virtual ~MyVector()
 {
 }

 void read()
 {
 std::string s;

 std::cout \> s)
 {
 push\_back(s);
 }

 std::cout c\_str(),pB-\>c\_str());
 }
};


int main()
{
 MyVector vData;

 vData.read();
 vData.sort();
 vData.print();

 return 0;
}

Einige Compiler moegen das static compare innerhalb der Klasse nicht, bei denen muesstest du es herausziehen. EOT ist das systemabhaengige End-Of-Text Zeichen (Unix Ctrl-D, Windows meistens Ctrl-Z)

Gruss
norsemanna

Hallo,
das Beispiel meines Vorredners ist sicherlich eleganter, aber um Dir weiterzuhelfen:
Du verwendest die Klasse „string“. Das ist lobenswert, aber ein Objekt vom Typ string hat keine Ähnlichkeit mit einem nullterminierten C-String!
string a(„Hallo“); *(char*)&a; zeigt nicht auf das 1. Zeichen im String.
Und es gibt kein abschließendes ‚\0‘.
Ich habe Dein Programm ein wenig umgeschrieben (und ausprobiert). Es tritt noch ein weiteres Problem auf: cin >> … liest normalerweise keine führenden WhiteSpaces, man kann also keinen leeren String eingeben. Ich habe deshalb einen einzelnen „.“ als Endekennung gewählt. Das Programm sortiert übrigens auch Zahlen und Sonderzeichen.
Grundsätzlich muss man sich aber fragen, ob das erbarmungslose Casten von Pointern wirklich guter Stil ist. Das schreit ja geradezu nach Fehlern, auch wirklich zerstörerischen. Vielleicht sollte man auf Funktionen mit void* lieber ganz verzichten, statt die Typprüfung des Compilers zu umgehen.

#include 
#include 
#include 

using namespace std;

//#define MAX 10
const int MAX = 10;

int compare( const void \*a, const void \*b );

void Programm\_1)
{
 string Eingabe[MAX];
 int i=0;

 cout \> Eingabe[i];
 i++;
 //}while(Eingabe[i-1] != "\0" || i == MAX );
 } while(Eingabe[i-1] != "." && i compare(\*(string\*)b);
}

mfg
Gert

Danke erstmal für die Hilfe und das gute Prog.

Ich habe jetzt noch einen Verbesserungsvorschlag an der Schleife, die für die Eingabe zuständig ist undzwar könnte ich die do-schleife heraus nehmen und durch eine for-Schleife ersetzen die in dem Fall wie folgt aussehen müßte:

for(i=0; Eingabe[i] != „.“ && i > Eingabe[i];

Gesagt getann.

Nun habe ich aber das Problem, das er die Schleife nicht verlässt auch wenn man den &-Operator durch ein |-Operator ersetzt.
Ich habe auch schon die MAX bedingung ganz entfernt doch ohne Erfolg.

Woran könnte es liegen?

Weil Du Eingabe[i] erst abfragts, dann beschreibts. Eingabe[i] ist bei der Abfrage immer leer. do {} while ist schon der richtige Ansatz.
mfg
Gert

Hallo.
Ich kann auf meiner Tastatur (Windows 7, Visual C++ 2008 Express) keine EOT-Tastenkombination finden. Weder ^D noch ^Z führen zum Abbruch.
mfg Gert

Vielen Dank für die Hilfe und die Schleife habe ich umgeschrieben in

for(i=1; Eingabe[i-1] != „.“ && i > Eingabe[i];

so klappt es.
Man kann auch statt dem Punkt als Abbruchbedingung „\0“ schreiben und muß dann in der Ausführung einfach STRg - Z drücken und mit Eingabe bestätigen.
Funkt auch.

MFG
P.

Ctrl-Z und Bug
Hi,

Ich kann auf meiner Tastatur (Windows 7, Visual C++ 2008
Express) keine EOT-Tastenkombination finden. Weder ^D noch ^Z
führen zum Abbruch.
mfg Gert

kann ich nicht nachvollziehen. Unter Express 2008 funktioniert das Programm im wesentlichen auch (nach dem Ctrl-Z muss man noch Enter eingeben). Lediglich der kleine Bug mit dem sizeof ist mir entgangen.

Es muss natuerlich sizeof(std::string) im qsort Call heissen.

Gruss
norsemanna

Hallo,

zu den ganzen Lösungen weiter unten möchte ich auch meinen Senf abgeben: Das macht man so aber nicht^^.

Auch wenn es augenscheinlich funktioniert, sollte man tunlichst vermeiden C und C++ auf diese Weise zu vermischen. Das bringt einem Früher oder Später nur Ärger ein.

Für solche Fälle gibts in C++ nämlich std::sort aus der algorithm.
Das kann deutlich besser mit std::string umgehen als qsort und ist nebenbei auch ein quicksort.

Grüße

Mimon,

Auch wenn es augenscheinlich funktioniert, sollte man tunlichst
vermeiden C und C++ auf diese Weise zu vermischen.

ob Dir dieses Urteil so zusteht, mögen andere beurteilen. Ich gebe zu bedenken, dass qsort sehr wohl im C++ Standard einen eigenen Abschnitt hat, mithin „legales“ C++ ist, während nirgendwo erwähnt wird, dass std::sort mit quicksort zu implementieren sei. Lediglich eine Vorgabe zur Laufzeit wird dort gemacht.

Das Beispiel verwendet qsort und std::string, weil der UP dieses benutzen wollte. Es funktioniert u.a., weil die Objekte sich nicht selbst referenzieren (also weder sich selbst noch andere Objekte im Array), was zum einen in der Tat ein fragwürdiger Programmierstil wäre und zum anderen auch mit std::sort zu Inkonsistenzen führen könnte.

Ansonsten gilt doch wohl, dass viele Wege nach Rom führen …

Gruss
norsemanna

Hui,

ich hab tatsächlich nur die Laufzeitangaben gesehen und ein quiksort draus abgeleitet^^.

Trozdem bleibt es eine Vergewaltigung der Klasse String und der Funktion qsort.

Was ist denn, wenn er anfängt eine eigene Klasse zu basteln, bei der nicht zufällig die Daten alle hintereinander im Speicher liegen? Und wenn man so sachen wie sizeof(string) lesen muss. Was ist, wenn mehr Daten als nur das Array gespeichert werden?

Ich hab nicht gesagt, das es verboten ist, nur das man es tunlichst meiden soll. Nur weil qsort im Standard enthalten ist, heißt es nicht, dass man es mit Klassen benutzen muss.
Versuch mal z.Bsp. printf und std::cin miteinander zu verwenden. Ist ja beides Standard aber will irgend wie nicht so richtig zusammenspielen.

Im Grunde bin ich einfach der Meinung, dass bloß weil ein veraltetes C eine Teilmenge vion C++ ist, ist das noch lange kein Grund alles wild durcheinander zu würfeln, sondern sollte da trennen, wo es möglich ist.

Grüße.

Das mit „\0“ klappt wohl nur zufällig. Richtig ist:

 for (int i = 0; (i \> Eingabe[i]); i++) {}

Der Operator >> gibt 0 (statt eine Referenz auf cin) zurück, wenn er auf ein Zeichen stößt, welches er nicht formatieren kann. Bei Strings ist das EOT (unter anderen?).

mfg
Gert