notorious.madeye Geschrieben 19. Oktober 2004 Geschrieben 19. Oktober 2004 Hallo, ich mal wieder . Diesmal habe ich das Problem, dass ich ein Array von Strings sortieren möchte, auch Ansätze existieren, ich aber mal wieder meinen Kopf gegen den Tisch ramme!!! Am besten lade ich auch mal den gesamten Code des Programms hoch, sodass ihr besser versteht was ich meine. KundenListe.cpp: // KundenListe.cpp: Implementierung der Klasse KundenListe. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "kunden_klasse5.h" #include "KundenListe.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Konstruktion/Destruktion ////////////////////////////////////////////////////////////////////// KundenListe::KundenListe() { m_iAnz=0; } KundenListe::~KundenListe() { } void KundenListe::NeuerKunde(int KundenNr, CString Vorname, CString Nachname) { if(m_iAnz==0) { m_iAnz++; m_pKunden=new Kunde*[m_iAnz]; } else { if(!ArrayVergroessern()) { return; } } m_pKunden[m_iAnz-1]=new Kunde(KundenNr, Vorname, Nachname); } bool KundenListe::ArrayVergroessern() { Kunde **Kunden=m_pKunden; m_iAnz++; m_pKunden=new Kunde*[m_iAnz]; for(int i=0; i<m_iAnz-1;i++) { m_pKunden[i]=Kunden[i]; } delete[] Kunden; return true; } void KundenListe::KundenAusgeben() { for(int i=0;i<m_iAnz;i++) { m_pKunden[i]->AusgabeName(); } } bool KundenListe::ArrayVerkleinern(int index) { int i=0; Kunde **Kunden=m_pKunden; m_iAnz--; m_pKunden=new Kunde*[m_iAnz]; while(i!=index) { m_pKunden[i]=Kunden[i]; i++; } i++; while(i<=m_iAnz) { m_pKunden[i-1]=Kunden[i]; i++; } delete[] Kunden; return true; } int KundenListe::KundenLoeschen(int KundenNr) { int index,wahl; for(int i=0;i<m_iAnz;i++) { index=m_pKunden[i]->GetKdNr(); if(index==KundenNr) { m_pKunden[i]->AusgabeName(); cout<<endl<<"Wollen Sie wirklich loeschen? 1.JA 2.NEIN"; cout<<endl<<"Ihre Wahl: "; cin>>wahl; switch(wahl) { case 1: ArrayVerkleinern(i); break; case 2: break; default: cout<<endl<<"Bitte waehlen Sie zwischen Ja und Nein!"; } index=i; return index; } } return 0; } void KundenListe::DateiSichern(int MaxKdNr) { CString a('\n'); char bufiAnz[2]; _itoa(m_iAnz, bufiAnz,10); char bufMaxKd[2]; _itoa (MaxKdNr,bufMaxKd,10); int KundenNr; CStdioFile Output; if(!Output.Open("liste.txt",CFile::modeWrite|CFile::modeCreate|CFile::typeText)) { cout<<endl<<"Fehler!"; } else { Output.WriteString(bufiAnz+a); Output.WriteString(bufMaxKd+a); for(int i=0;i<m_iAnz;i++) { KundenNr=m_pKunden[i]->GetKdNr(); itoa(KundenNr,bufiAnz,10); Output.WriteString(bufiAnz+a); Output.WriteString(m_pKunden[i]->GetVName()+a); Output.WriteString(m_pKunden[i]->GetNName()+a); } Output.Close(); } cout<<endl<<"Datei erfolgreich gespeichert!"<<endl; } void KundenListe::DateiEinlesen() { CString zwischen; CString Vorname; CString Nachname; int anzahl; int i=0; int KdNr; int KdNrMax; CStdioFile Input; Input.Open("liste.txt",CFile::modeRead|CFile::typeText); Input.ReadString(zwischen); anzahl=atoi(zwischen); Input.ReadString(zwischen); KdNrMax=atoi(zwischen); do { Input.ReadString(zwischen); KdNr=atoi(zwischen); Input.ReadString(Vorname); Input.ReadString(Nachname); NeuerKunde(KdNr, Vorname, Nachname); i++; }while(i<anzahl); Input.Close(); cout<<endl<<"Die Kundendatei wurde erfolgreich geladen!"; cout<<endl<<"Die Kundendatei enthaelt "<<anzahl<<" Eintraege."; cout<<endl<<"Die hoechste Kundennummer ist "<<KdNrMax<<"."<<endl; } int KundenListe::Vergleich() { int res; for(int i=0;i< res = strcoll( m_pKunden[i]->GetNName, m_pKunden[i+1]->GetNName()); return res; } void Kunde::AusgabeSortiert() { int i; qsort( m_pKunden[i], m_iAnz, sizeof(char *), KundenListe::Vergleich()); for (i = 0; i < 5; i++) { cout<<endl<<m_pKunden[i]->GetNName; } } Kunde.cpp: // Kunde.cpp: Implementierung der Klasse Kunde. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "kunden_klasse5.h" #include "Kunde.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Konstruktion/Destruktion ////////////////////////////////////////////////////////////////////// Kunde::Kunde() { } Kunde::~Kunde() { } Kunde::Kunde(int iKundenNr, CString cVorname, CString cNachname) { iKdNr=iKundenNr; m_cVorname=cVorname; m_cNachname=cNachname; } void Kunde::AusgabeName() { cout<<endl<<"~=:=:=:=:=:=:=:=:=:=:=~"; cout<<endl<<"Kundennummer: "<<iKdNr; cout<<endl<<"=-=-=-=-=-=-=-=-=-=-="; cout<<endl<<"Nachname:"<<(const TCHAR*)m_cNachname<<" Vorname:"<<(const TCHAR*)m_cVorname; cout<<endl<<"~=:=:=:=:=:=:=:=:=:=:=~"<<endl; } CString Kunde::GetNName() { return m_cNachname; } CString Kunde::GetVName() { return m_cVorname; } int Kunde::GetKdNr() { return iKdNr; } kunden_klasse5.cpp: // Kunden_klasse5.cpp : Definiert den Einsprungpunkt für die Konsolenanwendung. // #include "stdafx.h" #include "kunden_klasse5.h" #include "KundenListe.h" int MaxKdNr=0; int wahl, index, KundenNr, auswahl; char Vorname[30]; char Nachname[30]; void backupabfrage(); void neuerKunde(); void loeschen(); KundenListe * Kunden = new KundenListe(); void main() { while(true) { cout<<endl<<"~:~:~Kundenverwaltung~:~:~"; cout<<endl<<"Kunden anlegen___________1"; cout<<endl<<"Kunden loeschen__________2"; cout<<endl<<"Alle Kunden ausgeben_____3"; cout<<endl<<"Sortierte Ausgabe________4"; cout<<endl<<"Kundendatei speichern____5"; cout<<endl<<"Kundendatei laden________6"; cout<<endl<<"Programm verlassen_______7"; cout<<endl<<"Ihre Wahl________________"; cin>>auswahl; switch(auswahl) { case 1: neuerKunde(); break; case 2: loeschen(); break; case 3: Kunden->KundenAusgeben(); break; case 4: break; case 5: Kunden->DateiSichern(MaxKdNr); break; case 6: Kunden->DateiEinlesen(); break; case 7: backupabfrage(); break; default: cout<<endl<<"Falsche Eingabe, bitte wiederholen!"<<endl; break; } } } void neuerKunde() { cout<<endl<<"Vorname:"; cin>>Vorname; cout<<endl<<"Nachname:"; cin>>Nachname; MaxKdNr++; Kunden->NeuerKunde(MaxKdNr, Vorname, Nachname); } void backupabfrage() { cout<<endl<<"Vor dem Beenden speichern? 1.JA 2.NEIN"; cout<<endl<<"Ihre Wahl: "; cin>>wahl; if(wahl==1) { Kunden->DateiSichern(MaxKdNr); cout<<endl<<"Datei erfolgreich gespeichert!"<<endl; } exit(0); } void loeschen() { cout<<endl<<"Kundennummer:"; cin>>KundenNr; index=Kunden->KundenLoeschen(KundenNr); } Kunde.h: // Kunde.h: Schnittstelle für die Klasse Kunde. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_KUNDE_H__DF3F655F_0C09_49ED_9286_E17B75355C10__INCLUDED_) #define AFX_KUNDE_H__DF3F655F_0C09_49ED_9286_E17B75355C10__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "stdafx.h" class Kunde { public: Kunde(); virtual ~Kunde(); void AusgabeName(); CString GetNName(); CString GetVName(); int GetKdNr(); Kunde(int KundenNr, CString cVorname, CString cNachname); private: int iKdNr; CString m_cVorname; CString m_cNachname; }; #endif // !defined(AFX_KUNDE_H__DF3F655F_0C09_49ED_9286_E17B75355C10__INCLUDED_) kunden_klasse5.h: #if !defined(AFX_KUNDEN_KLASSE5_H__06C5A5E0_EF4C_4784_BC4E_FAD89DA08357__INCLUDED_) #define AFX_KUNDEN_KLASSE5_H__06C5A5E0_EF4C_4784_BC4E_FAD89DA08357__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "resource.h" #include "stdafx.h" #include "stdlib.h" #include "search.h" #include "fstream.h" #include "iostream.h" #include "stdio.h" #include "string.h" #endif // !defined(AFX_KUNDEN_KLASSE5_H__06C5A5E0_EF4C_4784_BC4E_FAD89DA08357__INCLUDED_) KundenListe.h: // KundenListe.h: Schnittstelle für die Klasse KundenListe. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_KUNDENLISTE_H__5CEFEA51_05E5_4E20_A40C_7D4EBCE73372__INCLUDED_) #define AFX_KUNDENLISTE_H__5CEFEA51_05E5_4E20_A40C_7D4EBCE73372__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "stdafx.h" #include "kunde.h" class KundenListe { public: KundenListe(); virtual ~KundenListe(); void NeuerKunde(int KundenNr, CString Vorname, CString Nachname); void KundenAusgeben(); void SortiertAusgeben(); int KundenLoeschen(int KundenNr); void DateiEinlesen(); void DateiSichern(int MaxKdNr); int Vergleich(); private: bool ArrayVergroessern(); bool ArrayVerkleinern(int Index); int m_iAnz; Kunde **m_pKunden; }; #endif // !defined(AFX_KUNDENLISTE_H__5CEFEA51_05E5_4E20_A40C_7D4EBCE73372__INCLUDED_) Den Nachnamen möchte ich über den Zeiger m_pKunden sortieren lassen und auch ausgeben. Zum sortieren wollt ich die Methoden am Ende der Datei KundenListe.cpp nutzen. Jaaa, ich würd auch lieber mit Vektoren arbeiten, aber das soll mit Arrays gelöst werden. Ich hoffe auf eure kompetente Hilfe und Danke schonmal jetzt, dass ihr euch überhaupt die Zeit gemacht habt, das zu lesen. Zitieren
Guybrush Threepwood Geschrieben 19. Oktober 2004 Geschrieben 19. Oktober 2004 Also ich hab mir den Code nicht angeguckt Wo genau ist denn jetzt dein Problem bei der Sortierung des Arrays? Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Die letzten 2 Methoden aus KundenListe.cpp wollen nich wie ich will. :mod: Nun klarer? Der Algorithmus stammt von http://cplus.kompf.de/artikel/locale.html falls es weiter hilft.... Zitieren
Klotzkopp Geschrieben 19. Oktober 2004 Geschrieben 19. Oktober 2004 Am besten lade ich auch mal den gesamten Code des Programms hoch, sodass ihr besser versteht was ich meine. Nein, nicht im geringsten. Wir wissen nicht, "wie du willst", und wir wissen auch nicht, "wie die 2 Methoden wollen". Zeige bitte nur den relevanten Code, sag, was der Code tun soll, und sag, was er statt dessen tut.Nein, nicht "am besten". Ich halte es für eine Frechheit, derart viel Code abzuladen, und dann die Fehlerbeschreibung auf "ich weiß nicht weiter" zu beschränken. Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Ich frag mich was du gleich so angep**** bist???? War ja gar nich bös gemeint. Ich meinte die Methoden Vergleich und AusgabeSortiert. Mit Vergleich möchte ich die einzelnen Nachnamen erst vergleichen auf <0, >0, bzw. ==, und dann mit AusgabeSortiert ausgeben. Das Nachnamen Array ist in kunde.h als Private Element, der Zeiger m_pKunde[] kann auf dieses Array zugreifen. int KundenListe::Vergleich() { int res; for(int i=0;i< res = strcoll( m_pKunden[i]->GetNName, m_pKunden[i+1]->GetNName()); return res; } void Kunde::AusgabeSortiert() { int i; char *words[] = {"Abfahrt", "Abfuhr", "Abführmittel", "Abfälle", "Abfall"}; qsort( m_pKunden[i], m_iAnz, sizeof(char *), KundenListe::Vergleich()); for (i = 0; i < 5; i++) { cout<<endl<<m_pKunden[i]->GetNName; } } Dies sind die beiden Methoden. Ach ja, tschuldigung, dies sind die Meldungen des Compilers: E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(192) : error C2664: 'strcoll' : Konvertierung des Parameters 1 von 'class CString (void)' in 'const char *' nicht moeglich Es gibt keinen Kontext, in dem diese Konvertierung moeglich ist E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(197) : error C2039: 'AusgabeSortiert' : Ist kein Element von 'Kunde' e:\msdev\projekte\test\kunden_klasse5\kunde.h(15) : Siehe Deklaration von 'Kunde' E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(202) : error C2065: 'm_pKunden' : nichtdeklarierter Bezeichner E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(202) : error C2109: Index benoetigt ein Feld oder einen Zeigertyp E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(202) : error C2065: 'm_iAnz' : nichtdeklarierter Bezeichner E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(202) : error C2352: 'KundenListe::Vergleich' : Unzulaessiger Aufruf einer nichtstatischen Member-Funktion e:\msdev\projekte\test\kunden_klasse5\kundenliste.h(28) : Siehe Deklaration von 'Vergleich' E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(205) : error C2109: Index benoetigt ein Feld oder einen Zeigertyp E:\Msdev\Projekte\Test\kunden_klasse5\KundenListe.cpp(205) : error C2227: Der linke Teil von '->GetNName' muss auf Klasse/Struktur/Union zeigen Fehler beim Ausführen von cl.exe. kunden_klasse5.exe - 8 Fehler, 0 Warnung(en) Zitieren
Klotzkopp Geschrieben 19. Oktober 2004 Geschrieben 19. Oktober 2004 Ich frag mich was du gleich so angep**** bist????Ich frage mich, wie du darauf kommst, dass ich das bin. qsort( m_pKunden, m_iAnz, sizeof(char *), KundenListe::Vergleich()); qsort erwartet als letzten Parameter einen Zeiger auf eine Funktion, die so aussieht: int NameEgal(const void*, const void*); Erstens ist KundenListe::Vergleich() kein Funktionszeiger, sondern ein Funktionsaufruf. Die Klammern sind zuviel. Zweitens passt die Signatur der Funktion nicht. KundenListe::Vergleich ist eine nichtstatische Memberfunktion und hat den Typ int(KundenListe::*)(). Du musst Vergleich entweder statisch machen oder nicht-Member. Außerdem musst du die const void*-Parameter hinzufügen. res = strcoll( m_pKunden->GetNName, m_pKunden[i+1]->GetNName()); Hier fehlen beim ersten GetNName die Klammern. Nachtrag: In Vergleich darf natürlich auch keine Schleife sein. Über die Parameter erhältst du die beiden Zeiger, die du vergleichen sollst. Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Erstens ist KundenListe::Vergleich() kein Funktionszeiger, sondern ein Funktionsaufruf. Schon klar, so ganz der Anfänger bin ich ja nu auch nicht. Zweitens passt die Signatur der Funktion nicht. KundenListe::Vergleich ist eine nichtstatische Memberfunktion und hat den Typ int(KundenListe::*)(). Du musst Vergleich entweder statisch machen oder nicht-Member. Außerdem musst du die const void*-Parameter hinzufügen. Als nicht Member-Funktion(==Methode) habe ich sie ja bereits in deklariert der KundenListe.h, wollte keine static Funktion daraus machen. Hast du dir denn mal den Link zum Algorithmus angesehen? Zitieren
Klotzkopp Geschrieben 19. Oktober 2004 Geschrieben 19. Oktober 2004 Als nicht Member-Funktion(==Methode) habe ich sie ja bereits in deklariert der KundenListe.h,Nein, du hast sie als Memberfunktion deklariert. qsort braucht entweder eine statische oder eine nicht-Member-Funktion (freie Funktion) wollte keine static Funktion daraus machen.Dann darf sie keine Memberfunktion sein. Hast du dir denn mal den Link zum Algorithmus angesehen? Ja. Hat aber nichts mit den Fehlern zu tun. Musst du qsort benutzen? Mit std::sort kämst du um die hässlichen void-Zeiger drumherum. Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Ich muss aber die Funktion Vergleich in KundenListe.cpp integrieren, damit ich mit dem Zeiger m_pKunden auf das Nachnamenarray zugreifen kann. Außerdem brauche ich m_iAnz als Zähler für die Schleife AusgabeSortiert....Oder fallen dir andere Möglichkeiten ein? Zitieren
Klotzkopp Geschrieben 19. Oktober 2004 Geschrieben 19. Oktober 2004 Ich muss aber die Funktion Vergleich in KundenListe.cpp integrieren, damit ich mit dem Zeiger m_pKunden auf das Nachnamenarray zugreifen kann. Außerdem brauche ich m_iAnz als Zähler für die Schleife AusgabeSortiert.... qsort ist eine C-Funktion und nicht für den Einsatz mit Klassen und Memberfunktionen geeignet. Du könntest deinen globalen Zeiger auf die Kundenliste-Instanz benutzen. Die globale Variable selbst ist aber schon schlechter Stil. Oder fallen dir andere Möglichkeiten ein? Nimm std::sort: #include <algorithm> // Prädikat struct NNComparePred { bool operator()(Kunde* k1, Kunde* k2) { return 0 > strcoll(k1->GetNName(), k2->GetNName()); } }; // Aufruf std::sort( m_pKunden, m_pKunden + m_iAnz, NNComparePred());[/CODE] Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Also die Alternative sieht sehr interessant aus. std::sort( m_pKunden, m_pKunden + m_iAnz, NNComparePred()); Kann ich diesen Aufruf aus der KundenListe.cpp mit einer einzelnen Funktion starten? Ist das struct vor NNComparePred gewollt? Bestimmt, aber wieso struct und wo soll ich sie einbinden? Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Also ich rufe jetzt in der kunden_klasse5.cpp eine Methode aus KundenListe.cpp auf, die ich mir jetzt erstellt habe. Der Aufruf sieht so aus: switch(auswahl) { case 1: neuerKunde(); break; case 2: loeschen(); break; case 3: Kunden->KundenAusgeben(); break; case 4: Kunden->AusgabeSortiert(); <-------------Relevante Zeile break; case 5: ..... In der KundenListe.cpp habe ich die Funktion folgendermaßen eingebunden: void KundenListe::AusgabeSortiert() { std::sort( m_pKunden, m_pKunden + m_iAnz, NNComparePred()); } Und die Definition der Methode in der KundenListe.h sieht so aus: class KundenListe { public: KundenListe(); virtual ~KundenListe(); void NeuerKunde(int KundenNr, CString Vorname, CString Nachname); void KundenAusgeben(); int KundenLoeschen(int KundenNr); void DateiEinlesen(); void DateiSichern(int MaxKdNr); void AusgabeSortiert(); <-------------Relevante Zeile! Die Frage ist jetzt nur, wie ich mit dem struct verfahren soll und wo ich es wie einbinden soll, da der Rest vom Compiler einwandfrei akzeptiert wird, noch zumindest Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Also, auf ein neues , die struct hab ich nun vor der Methode AusgabeSortiert eingebunden, und der Compiler meckert auch nicht mehr, aber wie kann ich den Spaß nun in richtiger Reihenfolge ausgeben? Zitieren
Klotzkopp Geschrieben 19. Oktober 2004 Geschrieben 19. Oktober 2004 aber wie kann ich den Spaß nun in richtiger Reihenfolge ausgeben? Das hattest du doch schon fast: for(i = 0; i < m_iAnz; ++i) { cout<<m_pKunden[i]->GetNName()<<endl; }[/CODE] Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Ja klar, nur wie muss ich das denn nun bitte umschreiben und wo am besten "hinstellen"? Weil durch das std::sort hat sich ja einiges geändert, oder wie? Zitieren
notorious.madeye Geschrieben 19. Oktober 2004 Autor Geschrieben 19. Oktober 2004 Jo, selbst gelöst, einfach hinter das std::sort.......... Einen SUUUUUUUUUUUUUUUUUUUUUPERLIEBEN Dank an Klotzkopp. :uli :uli :uli Wenn du das ganze Progg dennoch willst, sag bescheid. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.