c in c++



  • so,ich habe schon ein paar fragen...
    wofür steht das getline()
    getline(std::cin, nummer);

    wofür steht in dem zusammenhang das &
    PhoneBookEntry::PhoneBookEntry(const std::string& name, const std::string& number)

    warum hast du zwei klassen gamacht?
    class PhoneBook{
    class PhoneBookEntry{

    und was ist eine friend class?
    friend class PhoneBook;

    kann ich die ganzen funktionen zu einer funktion insert zusammen schließen?

    void insert(const std::string& name, const std::string& number);
        const std::string* getNumber(const std::string& name) const;
        const std::string& getName() const;
        const std::string& getNumber() const;
    

    meine headerdatei war wohl ein bischen doof reingestellt...

    void insert(phoneBook_t *book, char *name, char *num);
    

    soll namen und nummern einlesen und in search_name suchen ob es den namen schon gibt..

    char *getNumber(phoneBook_t *book, char *name);
    

    soll zu einem gegebenen namen die nummer suchen

    char *getName(phoneBook_t *book, char *num);
    

    soll zu einer gegebenen nummer den namen suchen

    void delete_it(phoneBook_t *book, char *name);
    

    einzelnen wert löschen

    void destroyBook(phoneBook_t *book);
    

    ganze buch löschen

    void list_book(phoneBook_t *book);
    

    buch auflisten

    int search_name(phoneBook_t *book, char *name);
    

    wird von insert aufgerufen soll nach doppelten namen suchen..

    weiteres folgt...



  • Steffi... schrieb:

    so,ich habe schon ein paar fragen...
    wofür steht das getline()
    getline(std::cin, nummer);

    Wie der Name schon sagt - hole eine Zeile. Das ist die C++ Alternative zu fgets().

    wofür steht in dem zusammenhang das &
    PhoneBookEntry::PhoneBookEntry(const std::string& name, const std::string& number)

    Übergabe per Referenz.

    warum hast du zwei klassen gamacht?
    class PhoneBook{
    class PhoneBookEntry{

    PhoneBook für ein komplettes Array, PhoneBookEntry für einen einzelnen Eintrag.

    und was ist eine friend class?
    friend class PhoneBook;

    Das ist eine Klasse, die auf die privaten Member zugreifen darf.

    kann ich die ganzen funktionen zu einer funktion insert zusammen schließen?

    void insert(const std::string& name, const std::string& number);
        const std::string* getNumber(const std::string& name) const;
        const std::string& getName() const;
        const std::string& getNumber() const;
    

    Wohl kaum - insert() fügt einen Eintrag, die anderen Methoden suchen nach bestehenden Einträgen.



  • ja danke!!
    dann werde ich wohl weiter probieren müssen...



  • HMm @CStoll ... nja fgets nicht ganz, da du ja nicht so einfach mit fopen zugriff auf die Consolenausgabe bekommst 😉 Wäre nen anderer stream angegeben, der dann bsw. ein file-stream wäre, dann wäre wohl fgets die C-Variante. Da hast de recht 😉



  • (D)Evil schrieb:

    HMm @CStoll ... nja fgets nicht ganz, da du ja nicht so einfach mit fopen zugriff auf die Consolenausgabe bekommst 😉

    Was will mir das jetzt sagen?
    fgets() bekommt ein FILE*, getline() einen istream (die C++ Entsprechung zu FILE* (für Eingabe-Dateien). Mit beiden kannst du von Tastatur (stdin bzw. cin - das mußt du übrigens auch nicht per open() der Konsole zuweisen) lesen, wenn du willst. Von daher ist getline() durchaus die logische Entsprechung zu fgets().



  • so ich hab noch ne frage in c gibt es //strcmp vergleicht die zeichenfolge
    gibt es sowas auch für strings(nicht für char) habe nichts in büchern gefunden

    kann man//copy anstelle für strncpy(strncpy nur für CHAR??) mit dem selben problem...

    wie schreib ich das in c++:

    printf("name:%6s nummer:%6s\n",inhalt->name,inhalt->number);
    

    kann man das?

    das wär es jetzt erst mal...Danke!

    denke bin der lösung meines programms nahe...hoffe ich...



  • joa kann man ...

    std::cout << "name: " << std::setw(6) << inhalt->name << " nummer: " << std::setw(6) << inhalt->number << std::endl;
    

    kann man//copy anstelle für strncpy(strncpy nur für CHAR??) mit dem selben problem...

    hmm ganz einfach ... die String-Klasse hat dafür nen operator:

    std::string s1("Das ist toll!");
    std::string s2 = s1;
    

    ...

    so ich hab noch ne frage in c gibt es //strcmp vergleicht die zeichenfolge
    gibt es sowas auch für strings(nicht für char) habe nichts in büchern gefunden

    String-Klasse(std::string) hat auch dafür nen operator (==) ...

    std::string s1("Das ist toll!");
    std::string s2 = s1;
    
    if (s1 == s2)
        std::cout << "\"" << s1 << "\" == \"" << s2 << "\"" << std::endl;
    


  • Danke sehr!!!

    habe schon wieder was neues...

    ich bekomme die fehlermeldung
    error C2451: Bedingter Ausdruck des Typs 'std::string' nicht zulässig

    und es wird dann dahin gezeigt...

    void PhoneBook::listbook(){
    	while(inhalt->next == NULL) {
    /*diese zeile..*/	if(inhalt->name)
    				inhalt = inhalt->next;
    				//cout << "name: " << std::setw(6) << inhalt->name << std::endl;
    				//cout<< " nummer: " << std::setw(6) << inhalt->number << std::endl;
    		}
    

    }

    weiß nicht wie ich das richtig machen muss...
    Danke!!



  • Nja du musst schon gucken auf was er testen soll ... aber auf if (inhalt->name == "") zu testen ... was soll das bringen?

    if (inhalt->name == "") /* an stelle von if (inhalt->name) */
    

    ... aber wo ist der Sinn?!



  • aber ist es in c nicht so,dass es das gleiche ist?
    if(inhalt->next == NULL){}
    if(inhalt->next){}

    habe es in meinem programm jetzt geändert aber dann bekomm ich nen haufen fehler ...
    error C2676: Binärer Operator '!=': 'std::string' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht

    error C2784: 'bool std::operator !=(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)': Vorlagenargument für 'const T1 *' von 'std::string' konnte nicht hergeleitet werden

    error C2784: 'bool std::operator !=(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)': Vorlagenargument für 'const T1 *' von 'int' konnte nicht hergeleitet werden

    error C2784: 'bool std::operator !=(const std::istream_iterator<_Ty,_Elem,_Traits,_Diff> &,const std::istream_iterator<_Ty,_Elem,_Traits,_Diff> &)': Vorlagenargument für 'const std::istream_iterator<_Ty,_Elem,_Traits,_Diff> &' von 'std::string' konnte nicht hergeleitet werden

    und noch viele mehr alle zeigen auf die selbe zeile...
    und die meisten auch mehrmals...



  • ? Also

    if(inhalt->next == NULL)
    

    würde folgendem entsprechen

    if(!inhalt->next)
    

    ...

    Da inhalt->name aber ein std::string und kein char* (bzw. überhaupt Zeiger) ist, kannst du schlecht auf NULL prüfen. Du musst prüfen ob der string leer ist.

    if (inhalt->name.empty() == true) // er ist leer!
    // if (inhalt->name.empty()) /* ist das selbe als wenn du auf true prüfst */
    

    ...



  • danke es läuft soweit,naja es kommen keine fehler meldungen mehr...
    meine Exception wirft sofort aus das es den namen schon gibt...
    also mal schaun wo ich in der search den fehler eingebaut habe...

    DANKE!!!



  • hab schon das nächste...

    void PhoneBook::insert(string name,string number){
    	element *eintrag;
    	if(search(name)){
    		throw xinsert();
    		return;
    	}
    	inhalt->name=name;		
        inhalt->number= number;
    	inhalt->next = NULL;
    
       while(eintrag->next != NULL)
    		eintrag = inhalt->next;
    		eintrag->next = eintrag;
    }
    

    warum gibt er mir ne warnung aus das er eintrag nicht kennt
    warning C4700: Lokale Variable 'eintrag' wurde ohne Initialisierung verwendet



  • nja das geht nicht was du da hast. Du musst "eintrag" auch auf was zeigen lassen ... momentan zeigt er ins Nirvana ...



  • aber wenn ich mit der maus auf eintrag->next gehe zeigt er mir das eintrag ein element*eintrag ist, und next element*element::next;ihm sind doch alle bekannt??



  • Ja er kennt die Variablen ... das ist klar. Aber du kannst ja nicht auf irgend eine Stelle im Speicher zeigen und erwarten das du da was verändern darfst!



  • wie kann ich das umgehen und insert liest trotzdem richtig ein?



  • Hallo zusammen,

    ich finde der Container map der Standardbibliothek eignet sich ganz hervorragend für solche Aufgaben. Hoffe, dass ich keine Verweise auf std::map beim übergliegen des Themas übersehen habe. Hier meine Lösung (weitesgehend ungetestet 🙂 ...

    // phonebook.h
    #ifndef __PHONEBOOK_H__
    #define __PHONEBOOK_H__
    
    #include <string>
    #include <map>
    #include <iostream>
    
    class PhoneBook {
      typedef unsigned int value_type;
      typedef std::map<std::string, value_type> container_type;
      container_type v;
    
    public:
      typedef value_type number_type;
      void insert(const std::string &name, number_type number);
    
      number_type getNumber(const std::string &name);
      std::string getName(number_type number);
      bool listBook(std::ostream &os);
    };
    
    #endif
    
    // phonebook.cpp
    #include "phonebook.h"
    using namespace std;
    
    void PhoneBook::insert(const string &name, number_type number) {
      v[name] = number;
    }
    
    PhoneBook::number_type PhoneBook::getNumber(const string &name) {
      return v[name];
    }
    
    string PhoneBook::getName(number_type number) {
      container_type::const_iterator i = v.begin();
      while (i != v.end()) {
        if (i->second == number)
          return i->first;
        ++i;
      }
    }
    
    bool PhoneBook::listBook(ostream &os) {
      container_type::const_iterator i = v.begin();
      while (i != v.end()) {
        os << i->first << ": " << i->second << endl;
        ++i;
      }
    }
    
    // main.cpp
    #include <iostream>
    #include <string>
    #include <cassert>
    #include "phonebook.h"
    using namespace std;
    
    int main()
    {
      PhoneBook v;
    
      v.insert("lucky_tux", 1234567);
      v.insert("Martin", 123);
      v.insert("P1", 124);
      v.insert("P2", 125);
    
      assert(v.getNumber("lucky_tux") == 1234567);
      assert(v.getName(1234567) == "lucky_tux");
    
      v.listBook(cout);
    }
    

    Was haltet ihr von diesem Ansatz? Bin wie immer auch über negative Kritik dankbar...

    Grüße Martin



  • von deinen Ganzen typedefs halte ich recht wenig ... nutz einfach durchgehen den std::size_t - Typ und fertig.



  • (D)Evil schrieb:

    von deinen Ganzen typedefs halte ich recht wenig ... nutz einfach durchgehen den std::size_t - Typ und fertig.

    Wie der Name ja schon sagt, ist size_t ursprünglich für Größenangaben gedacht. Deswegen könnte die Verwendung von size_t ein wenig verwirrend sein?

    Danke für den Hinweis.


Anmelden zum Antworten