Dateistruktur
-
[gelöst]
Hallo,
ich habe nicht viel Erfahrung mit c++, wollte aber das Programm Eliza in kleinere Dateien zerlegen, doch das gelingt mir nicht, weil ich nicht weiß wie das genau funktioniert. Die einzelne cpp-Datei wird ohne Probleme kompiliert. Versuche ich meine Aufteilung bekomme ich tausende von Fehlermeldungen.Hoffe ihr könnt mir weiterhelfen. Gegooglet habe ich auch schon, konnte aber nichts finden, weil ich nicht genau weiß mit welchen Suchbegriffen ich suchen soll.
Der Code:
#include <iostream> #include <string> #include <vector> using namespace std; class tStichwort { public: string Wort; int ID; }; 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} }; class tAntwort { public: long Aufrufe; string Antwort; }; 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: $?"} }; 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?" } }; class tBindung { public: long WortID; long AntwortID; }; 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} }; 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; } int main() { string Aussage; while (true) { getline(cin, Aussage); vector<string> Woerter; zerlegeInWoerter(Aussage, Woerter); string Antwort; sucheNachAntwort(Woerter, Antwort); cout << Antwort << endl; } }Kann man hier auch Dateien hochladen?? Würde gerne meine Aufteilung zeigen, um die Fehler zu sehen.
Meine Aufteilung: main.cpp, klassen.h, antworten.cpp, bindungen.cpp, phrasen.cpp, stichwoerter.cpp und funktionen.cppViele Grüße
-
Es wird vermutlich auf fehlende Deklarationen, Zirkelbezüge usw. hinauslaufen, aber poste bitte mal die Fehlermeldungen, dann kann man zu jeder was Genaues sagen.
Btw, wenn du lernen willst, wie du ein Programm korrekt und sinnvoll auf mehrere Dateien aufteilen kannst, solltest du das vielleicht erst mal an einem eigenen Programm versuchen. Ich schätze, dass du auf diesem Weg eher ein Verständnis für die Sache entwickeln würdest.
-
Danke dir, ich werd es auch mit eigenem Code versuchen.
Die Fehlermeldung:
In file included from main.cpp:4: klassen.h:8: error: ‘string’ does not name a type klassen.h:15: error: ‘string’ does not name a type 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 In file included from antworten.cpp:1: klassen.h:8: error: ‘string’ does not name a type klassen.h:15: error: ‘string’ does not name a type antworten.cpp:8: error: expected ‘}’ before ‘{’ token antworten.cpp:8: error: too many initializers for ‘tAntwort’ antworten.cpp:8: error: too many initializers for ‘tAntwort’ antworten.cpp:8: error: too many initializers for ‘tAntwort’ 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 In file included from bindungen.cpp:1: klassen.h:8: error: ‘string’ does not name a type klassen.h:15: error: ‘string’ does not name a type In file included from phrasen.cpp:1: klassen.h:8: error: ‘string’ does not name a type klassen.h:15: error: ‘string’ does not name a type phrasen.cpp:7: error: expected ‘}’ before ‘{’ token phrasen.cpp:7: error: too many initializers for ‘tAntwort’ phrasen.cpp:7: error: too many initializers for ‘tAntwort’ phrasen.cpp:7: error: too many initializers for ‘tAntwort’ 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 In file included from stichwoerter.cpp:1: klassen.h:8: error: ‘string’ does not name a type klassen.h:15: error: ‘string’ does not name a type stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: too many initializers for ‘tStichwort’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ stichwoerter.cpp:7: error: invalid conversion from ‘const char*’ to ‘int’ In file included from funktionen.cpp:4: klassen.h:8: error: ‘string’ does not name a type klassen.h:15: error: ‘string’ does not name a type 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
-
Meine falsche Ordnung, wollte erstmal das ganze weglassen weil es zu viel wird, aber ich denke es ist doch besser, um zu sehen was ich falsch gemacht habe:
main.cpp:
#include <iostream> #include <string> #include <vector> #include "klassen.h" using namespace std; int main( void ) { string Aussage; while( true ) { getline( cin, Aussage ); vector<string> Woerter; zerlegeInWoerter( Aussage, Woerter ); string Antwort; sucheNachAntwort( Woerter, Antwort ); cout << Antwort << endl; } return 0; }klassen.h:
#ifndef _EKLASSEN_H_ #define _EKLASSEN_H_ #include <string> class tStichwort { public: string Wort; int ID; }; class tAntwort { public: long Aufrufe; string Antwort; }; class tBindung { public: long WortID; long AntwortID; }; #endifantworten.cpp:
#include "klassen.h" tAntwort Antworten[] = { {0, "Dein $ ist Dir sehr wichtif, nicht wahr?"}, {0, "Hättest Du nicht darüber mit Deinem $ sprechen sollen?"}, {0, "Erzähle mehr über Deine Beziehung zu Deinem $!"} {0, "Deine $ ist Dir sehr wichtif, nicht wahr?"}, {0, "Hättest Du nicht darüber mit Deiner $ sprechen sollen?"}, {0, "Erzähle mehr über Deine Beziehung zu Deiner $!"} {0 ,"$ ist keine echte Lösung."} {0, "Es ist nich gut mit $ zu leben."} {0, "Sollte die Welt nicht auf $ verzichten?"} {0, "Was bedeutet das eigentlich für Dich: $?"} };bindungen.cpp:
#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} };phrasen.cpp:
#include "klassen.h" tAntwort Phrasen[] = { {0, "Ich verstehe Deine Zurückhaltung."}, {0, "Solltest Du nicht offener von Die 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?"} };stichwoerter.cpp:
#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} };funktionen.cpp:
#include <iostream> #include <string> #include <vector> #include "klassen.h" using namespace std; bool istBuchstabe( char Zeichen ) { if( Zeichen>='a' && Zeichen<='z' ) return true; if( Zeichen>='A' && Zeichen<='Z' ) return true; 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; }
-
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.