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 );
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)
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);
}
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.
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.
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.
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.
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 …
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.
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?).