Dateistruktur
-
in Klassen.h hast du
using namespace std;vergessen
dadurch ist der Typ string unbekannt und deshalb kommen dort die Fehlermeldungen dadurch ist die gesamte Klassendefinition ungültig und die Klassen, die einen string haben, können nicht initialisiert werden.
Also entweder den namespace std benutzen, oderstd::stringstatt
stringin den Klassendefinitionen schreiben

-
Hab ich jetzt eingefügt. Bekomme jetzt diese Meldung:
main.cpp: In function ‘int main()’: main.cpp:13: error: ‘zerlegeInWoerter’ was not declared in this scope main.cpp:15: error: ‘sucheNachAntwort’ was not declared in this scope antworten.cpp:8: error: expected ‘}’ before ‘{’ token antworten.cpp:8: error: expected ‘,’ or ‘;’ before ‘{’ token antworten.cpp:8: error: expected unqualified-id before ‘,’ token antworten.cpp:9: error: expected unqualified-id before ‘{’ token antworten.cpp:9: error: expected unqualified-id before ‘,’ token antworten.cpp:10: error: expected unqualified-id before ‘{’ token antworten.cpp:12: error: expected unqualified-id before ‘{’ token antworten.cpp:13: error: expected unqualified-id before ‘{’ token antworten.cpp:14: error: expected unqualified-id before ‘{’ token antworten.cpp:16: error: expected unqualified-id before ‘{’ token antworten.cpp:17: error: expected declaration before ‘}’ token phrasen.cpp:7: error: expected ‘}’ before ‘{’ token phrasen.cpp:7: error: expected ‘,’ or ‘;’ before ‘{’ token phrasen.cpp:7: error: expected unqualified-id before ‘,’ token phrasen.cpp:8: error: expected unqualified-id before ‘{’ token phrasen.cpp:8: error: expected unqualified-id before ‘,’ token phrasen.cpp:9: error: expected unqualified-id before ‘{’ token phrasen.cpp:10: error: expected declaration before ‘}’ token funktionen.cpp: In function ‘long int holeAntwort(long int)’: funktionen.cpp:33: error: ‘Bindungen’ was not declared in this scope funktionen.cpp:37: error: ‘Antworten’ was not declared in this scope funktionen.cpp: In function ‘long int holePhrase()’: funktionen.cpp:59: error: ‘Phrasen’ was not declared in this scope funktionen.cpp: In function ‘void sucheNachAntwort(std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::string&)’: funktionen.cpp:72: error: ‘Stichwoerter’ was not declared in this scope funktionen.cpp:82: error: ‘Antworten’ was not declared in this scope funktionen.cpp:94: error: ‘Phrasen’ was not declared in this scope
-
Nimm niemals using namspace std in Headerdateien. Für Gründe dafür nutze die Forumssuche.
Gibt es eine funktionen.h? Die sollte es zumindest geben und auch in main inkludiert sein. Woher sollte die main deine Funktionen sonst kennen?
-
bei antworten.cpp fehlt hinter den geschweiften Klammern in einigen Zeilen jeweils die Kommata. In phrasen.cpp fehlt auch ein Komma nach einer geschweiften Klammer.
Der Poster vor mir hat recht... lieber in Headerfile
std::stringbenutzen und in den .cpp's
using namespace std;auf den Namespace wechseln.
Und die anderen Fehler behebst du, indem du die erwähnte Headerdatei für die Funktionen schreibst

-
Hab jetzt ales gemacht, was ihr gesagt habt.
Bekomme jetzt aber komischerweise diese Meldung, obwohl die Funktionen deklariert sind:main.cpp: In function ‘int main()’: main.cpp:19: error: ‘zerlegeInWoerter’ was not declared in this scope main.cpp:21: error: ‘sucheNachAntwort’ was not declared in this scope
-
ploib_ schrieb:
Hab jetzt ales gemacht, was ihr gesagt habt.
Bekomme jetzt aber komischerweise diese Meldung, obwohl die Funktionen deklariert sind:main.cpp: In function ‘int main()’: main.cpp:19: error: ‘zerlegeInWoerter’ was not declared in this scope main.cpp:21: error: ‘sucheNachAntwort’ was not declared in this scopeWie sieht deine main.cpp aus und die darin eingebundenen Header (abgesehn von Standard-Headern)?
Ohne den aktuellen Stand können wir dir nicht sagen was am aktuellen Stand falsch ist...
-
Header:
#include "klassen.h"
#include "antworten.h"
#include "bindungen.h"
#include "phrasen.h"
#include "stichwoerter.h"
#include "funktionen.h"antwort.cpp, bindungen.cpp, phrasen.cpp und stichwoerter.cpp habe ich in .h-Dateien umgeschrieben, sollte man das machen oder nicht??
In funktionen.cpp habe ich auch all diese Header-Dateien eingefügt.
-
ploib_ schrieb:
antwort.cpp, bindungen.cpp, phrasen.cpp und stichwoerter.cpp habe ich in .h-Dateien umgeschrieben, sollte man das machen oder nicht??
Klares jein. Wenn du Funktionen im Header definierst, bekommst du beim Linken Probleme mit der One Definition Rule (ODR), sobald du den Header mehr als einmal irgendwo einbindest.
Die klassische Lösung ist, die Funktionen im Header nur zu deklarieren und in der .cpp zu definieren, wobei die .cpp den header einbindet (genauso wie deine main.cpp)Kurzes Beispiel:
f.h://nur Deklaration void f(int i);f.cpp:
#include <iostream> #include "f.h" void f(int i) { std::cout << "i: " << i << std::endl; }main.cpp:
#include "f.h" int main() { for (int i = 1; i < 1000; i *= 2) { f(i); } }Zu deiner Fehlermeldung: Heißt die Funktion im Header auch wirklich so wie du sie in der main() buchstabiert hast? Zeig uns ggf. nochmal deinen kompletten Code, wie er jetzt aussieht - ist ja nicht so viel

-
main.cpp:
#include <iostream> #include <string> #include <vector> #include "klassen.h" #include "antworten.h" #include "bindungen.h" #include "phrasen.h" #include "stichwoerter.h" #include "funktionen.h" using namespace std; int main() { string Aussage; while (true) { getline(cin, Aussage); vector<string> Woerter; zerlegeInWoerter(Aussage, Woerter); string Antwort; sucheNachAntwort(Woerter, Antwort); cout << Antwort << endl; } }klassen.h:
#ifndef _EKLASSEN_H_ #define _EKLASSEN_H_ #include <string> class tStichwort { public: std::string Wort; int ID; }; class tAntwort { public: long Aufrufe; std::string Antwort; }; class tBindung { public: long WortID; long AntwortID; }; #endifantworten.h:
#ifndef _EANTWORTEN_H_ #define _EANTWORTEN_H_ #include "klassen.h" tAntwort Antworten[] = { {0, "Dein $ ist Dir sehr wichtig, nicht wahr?" }, {0, "Hättest Du darüber nicht mit Deinem $ sprechen sollen?"}, {0, "Erzähle mehr über die Beziehung zu Deinem $!"}, {0, "Deine $ ist Dir sehr wichtig, nicht wahr?" }, {0, "Hättest Du darüber nicht mit Deiner $ sprechen sollen?"}, {0, "Erzähle mehr über die Beziehung zu Deiner $!"}, {0, "$ ist keine echte Lösung."}, {0, "Es ist nicht gut, mit $ zu leben."}, {0, "Sollte die Welt nicht auf $ verzichten?"}, {0, "Was bedeutet das eigentlich für Dich: $?"} }; #endifbindungen.h:
#ifndef _EBINDUNGEN_H_ #define _EBINDUNGEN_H_ #include "klassen.h" tBindung Bindungen[] = { {1, 0}, {1, 1}, {1, 2}, {2, 3}, {2, 4}, {2, 5}, {3, 6}, {3, 7}, {3, 8}, {1, 9}, {2, 9}, {3, 9} }; #endifphrasen.h:
#ifndef _EPHRASEN_H_ #define _EPHRASEN_H_ #include "klassen.h" tAntwort Phrasen[] = { { 0, "Ich verstehe Deine Zurückhaltung." }, { 0, "Solltest Du nicht offener von Dir reden?" }, { 0, "Was meinst Du ist denn die Ursache von all dem?" }, { 0, "Kannst Du etwas präziser werden?" }, { 0, "Du solltest nicht alles in Dich hineinfressen." }, { 0, "Fühlst Du Dich in dieser Hinsicht unsicher?" } }; #endifstichwoerter.h:
#ifndef _ESTICHWOERTER_H_ #define _ESTICHWOERTER_H_ #include "klassen.h" tStichwort Stichwoerter[] = { {"Bruder", 1}, {"Vater", 1}, {"Sohn", 1}, {"Opa", 1}, { "Freund", 1}, { "Mutter", 2}, {"Schwester", 2}, { "Tochter", 2}, {"Oma", 2}, {"Gewalt", 3}, {"Druck", 3}, {"Schweigen", 3} }; #endiffunktionen.cpp:
#include <iostream> #include <string> #include <vector> #include "klassen.h" #include "antworten.h" #include "bindungen.h" #include "phrasen.h" #include "stichwoerter.h" using namespace std; bool istBuchstabe(char Zeichen) { if (Zeichen>='a' && Zeichen<='z') return true; if (Zeichen>='A' && Zeichen<='Z') return true; // Mit UTF-8 wird das mit den Umlauten nicht so einfach return false; } void zerlegeInWoerter(const string &Satz, vector<string> &Woerter) { int Laenge = Satz.length(); int Pos = 0; int Anfang; Woerter.clear(); while (Pos<Laenge) { while (Pos<Laenge && !istBuchstabe(Satz[Pos])) Pos++; Anfang = Pos; while (Pos<Laenge && istBuchstabe(Satz[Pos])) Pos++; Woerter.push_back(Satz.substr(Anfang, Pos-Anfang)); } } long holeAntwort(long WortID) { long min=999999; long minID = -1; long AntwortID; long MaxBindungen=sizeof(Bindungen)/sizeof(Bindungen[0]); for (long bi=0; bi<MaxBindungen; ++bi) { if (Bindungen[bi].WortID==WortID) { AntwortID = Bindungen[bi].AntwortID; if (min>Antworten[AntwortID].Aufrufe) { minID=AntwortID; min=Antworten[AntwortID].Aufrufe; --Antworten[AntwortID].Aufrufe; } } } return minID; } void ersetzePlatzHalter(string &Antwort, const string &Wort) { unsigned long pos = Antwort.find("$"); if (pos!=string::npos) { Antwort.replace(pos, 1, Wort); } } long holePhrase() { long min=999999; long minID = -1; long MaxPhrasen = sizeof(Phrasen)/sizeof(Phrasen[0]); for (long i=0; i<MaxPhrasen; ++i) { if (min>Phrasen[i].Aufrufe) { minID=i; min=Phrasen[i].Aufrufe; --Phrasen[i].Aufrufe; } } return minID; } void sucheNachAntwort(vector<string> &Woerter, string& Antwort) { long MaxStichwoerter=sizeof(Stichwoerter) /sizeof(Stichwoerter[0]); vector<string>::iterator it; for (it=Woerter.begin(); it!=Woerter.end(); ++it) { for (long wi=0; wi<MaxStichwoerter; ++wi) { if (*it == Stichwoerter[wi].Wort) { long ID = Stichwoerter[wi].ID; long AntwortID = holeAntwort(ID); // Nun sollten wir eine ID haben if (AntwortID>=0) { Antwort = Antworten[AntwortID].Antwort; ersetzePlatzHalter(Antwort, *it); // Diese Antwort etwas zurückstellen Antworten[AntwortID].Aufrufe+=10; // wir gehen mal einfach return; } } } } // Kein Stichwort gefunden. Wir faseln... long AntwortID = holePhrase(); Antwort = Phrasen[AntwortID].Antwort; // Diese Antwort etwas zurückstellen Phrasen[AntwortID].Aufrufe+=10; }funktionen.h:
#ifndef _EKLASSEN_H_ #define _EKLASSEN_H_ bool istBuchstabe(char Zeichen); void zerlegeInWoerter(const string &Satz, vector<string> &Woerter); long holeAntwort(long WortID); void ersetzePlatzHalter(string &Antwort, const string &Wort); long holePhrase(); void sucheNachAntwort(vector<string> &Woerter, string& Antwort); #endifJa, die Namen der Funktionen sind identisch.
-
Hallo,
Fehler kommentiert
#ifndef _EKLASSEN_H_ // Includeguards gleich wie bei klassen.h, include wird damit verhindert. Umbenennen! #define _EKLASSEN_H_ bool istBuchstabe(char Zeichen); void zerlegeInWoerter(const string &Satz, vector<string> &Woerter); //namespace std:: vor string und vector vergessen long holeAntwort(long WortID); void ersetzePlatzHalter(string &Antwort, const string &Wort); long holePhrase(); void sucheNachAntwort(vector<string> &Woerter, string& Antwort); #endif
-
Jetzt bekomme ich diese Fehlermeldung:
/tmp/cccNimqL.o:(.bss+0x0): multiple definition of `Antworten' /tmp/ccTSoNaF.o:(.bss+0x0): first defined here /tmp/cccNimqL.o:(.data+0x0): multiple definition of `Bindungen' /tmp/ccTSoNaF.o:(.data+0x0): first defined here /tmp/cccNimqL.o:(.bss+0x60): multiple definition of `Phrasen' /tmp/ccTSoNaF.o:(.bss+0x60): first defined here /tmp/cccNimqL.o:(.bss+0xa0): multiple definition of `Stichwoerter' /tmp/ccTSoNaF.o:(.bss+0xa0): first defined here collect2: ld returned 1 exit status
-
Ich habe es jetzt gelöst. Vielen Dank für eure Hilfe.
In der main.cpp mussten die includes
#include "antworten.h"
#include "bindungen.h"
#include "phrasen.h"
#include "stichwoerter.h"entfernen.
Ich habe jetzt sehr viel dazugelernt. Danke
-
ploib_ schrieb:
Jetzt bekomme ich diese Fehlermeldung:
/tmp/cccNimqL.o:(.bss+0x0): multiple definition of `Antworten' /tmp/ccTSoNaF.o:(.bss+0x0): first defined here /tmp/cccNimqL.o:(.data+0x0): multiple definition of `Bindungen' /tmp/ccTSoNaF.o:(.data+0x0): first defined here /tmp/cccNimqL.o:(.bss+0x60): multiple definition of `Phrasen' /tmp/ccTSoNaF.o:(.bss+0x60): first defined here /tmp/cccNimqL.o:(.bss+0xa0): multiple definition of `Stichwoerter' /tmp/ccTSoNaF.o:(.bss+0xa0): first defined here collect2: ld returned 1 exit statusDas ist genau das was ich oben mit Verletzung der ODR gemeint habe. Die includes aus der Main zu entfernen behebt nur die Symptome, nicht die Ursache (nämlich, dass du die Funktionen non-inline im Header definiert hast).
Schau dir am Besten mal entsprechende Infos zum Arbeiten mit mehreren Übersetzungseinheiten im Buch deiner Wahl oder im Netz an.
-
Ich verstehe nicht was ich genau in den Header-Dateien falsch gemacht habe.
z.B.:
#ifndef _EANTWORTEN_H_ #define _EANTWORTEN_H_ #include "klassen.h" tAntwort Antworten[] = { {0, "Dein $ ist Dir sehr wichtig, nicht wahr?" }, {0, "Hättest Du darüber nicht mit Deinem $ sprechen sollen?"}, {0, "Erzähle mehr über die Beziehung zu Deinem $!"}, {0, "Deine $ ist Dir sehr wichtig, nicht wahr?" }, {0, "Hättest Du darüber nicht mit Deiner $ sprechen sollen?"}, {0, "Erzähle mehr über die Beziehung zu Deiner $!"}, {0, "$ ist keine echte Lösung."}, {0, "Es ist nicht gut, mit $ zu leben."}, {0, "Sollte die Welt nicht auf $ verzichten?"}, {0, "Was bedeutet das eigentlich für Dich: $?"} }; #endifDas ist keine Funktion

-
ploib_ schrieb:
Das ist keine Funktion

Der von dir gepostete Code verletzt die ODR:
ISO/IEC 14882:2003, Abschnitt 3.2 schrieb:
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type or template.
Die Variable Antworten wird in jeder Übersetzungseinheit definiert, die die entsprechende Header-Datei inkludiert. Entweder deklarierst du Antworten als const oder verschiebst ihre Definition in eine Übersetzungseinheit.
-
pumuckl schrieb:
//nur Deklaration void f(int i);inline vergessen.