undefined reference to...
-
Hallo @ all,
wir haben die Aufgabe bekommen in ziemlich kurzer Zeit c++ zu lernen und anzuwenden. Leider ist das ziemlich schwierig. Ich habe die Aufgabe ein WIKI zu programmieren. Hier nun meine Frage. Ich habe eine Methode in der Datei Werkzeug.cpp und der Klasse Werkzeug. Die Methode heisst parseStream(). Sie erwartet einen String und soll einen map Container mit jeweils zwei Strings zurückgeben. Leider bekomme ich die Fehlermeldung "undefined reference to.."
hier nun erstmal die Header Datei der Werkzeug Klasse:
#ifndef _Werkzeug_h_ #define _Werkzeug_h_ #include <iostream> #include <dirent.h> #include <cstdlib> #include <string> #include <list> #include <map> using namespace std; class Werkzeug { public: Werkzeug (); //Konstruktor ~Werkzeug(); //Destruktor string ersetze(string s, string s1, string s2); string searchReplace(string searchstring); string directory(string verz, string mask); list<string> split (string str, char tr); map <string, string> parseStream(string str); private: string _Zeichenkette, _searchstring, _s, _s1, _s2; }; #endif
Dann noch der Code der Werkzeug Klasse an sich:
#include "Werkzeug.h" Werkzeug::Werkzeug() {}; Werkzeug::~Werkzeug() {}; string Werkzeug::ersetze(string s, string s1, string s2) { int l = s1.length(); int i = s.find(s1); while(i != string::npos) { s.replace(s.find(s1),l, s2); i++; i = s.find(s1, i); } return s; } string Werkzeug::searchReplace(string searchstring) { searchstring = ersetze(searchstring,"+"," "); searchstring = ersetze(searchstring,"%0D%0A","\n"); searchstring = ersetze(searchstring,"%21","!"); searchstring = ersetze(searchstring,"%22","\""); //backslash vor dem Ausrufezeichen sagt dem Compiler, das folgende Zeichen ist kein Programmcode searchstring = ersetze(searchstring,"%23","#"); searchstring = ersetze(searchstring,"%24","$"); searchstring = ersetze(searchstring,"%25","%"); searchstring = ersetze(searchstring,"%26","&"); searchstring = ersetze(searchstring,"%27","´"); searchstring = ersetze(searchstring,"%28","("); searchstring = ersetze(searchstring,"%29",")"); searchstring = ersetze(searchstring,"%2B","+"); searchstring = ersetze(searchstring,"%2C",","); searchstring = ersetze(searchstring,"%2F","/"); searchstring = ersetze(searchstring,"%3A",":"); searchstring = ersetze(searchstring,"%3B",";"); searchstring = ersetze(searchstring,"%3C","<"); searchstring = ersetze(searchstring,"%3D","="); searchstring = ersetze(searchstring,"%3E",">"); searchstring = ersetze(searchstring,"%3F","?"); searchstring = ersetze(searchstring,"%5C","\\"); //backslash vor dem backslash sagt dem Compiler, das folgende Zeichen ist kein Programmcode searchstring = ersetze(searchstring,"%60","`"); searchstring = ersetze(searchstring,"%7B","{"); searchstring = ersetze(searchstring,"%7C","|"); searchstring = ersetze(searchstring,"%7D","}"); searchstring = ersetze(searchstring,"%7E","~"); searchstring = ersetze(searchstring,"%B4","'"); searchstring = ersetze(searchstring,"%C4","Ä"); searchstring = ersetze(searchstring,"%D6","Ö"); searchstring = ersetze(searchstring,"%DC","Ü"); searchstring = ersetze(searchstring,"%E4","ä"); searchstring = ersetze(searchstring,"%F6","ö"); searchstring = ersetze(searchstring,"%FC","ü"); return searchstring; } string Werkzeug::directory(string verz, string mask) { DIR *hdir; struct dirent *entry; int inl_slaenge = 0; string fn, list, z; char verzc[20]=" "; const char *verz1, *mask1, *z1; verz1 = verz.c_str(); //strcpy( verzc, verz1); mask1 = mask.c_str(); //verz.c_str(); hdir = opendir(verz1); do { entry = readdir(hdir); if (entry) { inl_slaenge = strlen(entry->d_name); z = entry->d_name+inl_slaenge-4; z1 = z.c_str(); if ((strcmp(mask1, z1) == 0)) { fn = entry->d_name; //Konvertieren des Dateinamens in einen String fn.replace(fn.find(mask),4,""); //Dateiendung inklusive Punkt abschneiden fn = "<a href=\""+verz+fn+mask+"\">"+fn+"</a>"; //erzeugen eines Links list = list + fn + "<br>\n"; } } } while (entry); closedir(hdir); return list; } //static string quoted(const string &src); list<string> split (string str, char tr) { list<string> strElemente; // Ergebnis: Liste von Teilstrings string::iterator pos1, // Anfang/Ende von pos2; // Teilstrings pos1 = str.begin(); // Beginn eines Teilstrings pos2 = find (pos1, str.end(), tr); // Ende eines Teilstrings while ( pos2 != str.end()) { // Trenner als Ende gefunden assert(*pos2==tr); string elem; // Teilstring copy (pos1, pos2, back_inserter(elem)); // Teilstring kopieren strElemente.push_back(elem); // Teilstring speichern pos1 = pos2; ++pos1; // neuer Anfang hinter altem Ende pos2 = find (pos1, str.end(), tr); // neue Suche } // pos2 zeigt auf das Ende. pos1 zeigt auf den Beginn // des letzten Teilstrings vor dem Ende. // Letzten Teilstring extrahieren: // string last; copy (pos1, str.end(), back_inserter(last)); strElemente.push_back(last); return strElemente; } map <string, string> parseStream(string str) { list<string> feldListe = split(str, '&'); // in Felder zerlegen map< string,string > felder; // Ergebnis // Felder in Paare aus Feldnamen und Wert splitten // for ( list<string>::iterator i = feldListe.begin(); i != feldListe.end(); ++i){ list<string> feldStr = split(*i, '='); pair< string, string > feld; feld.first = feldStr.front(); // Feldname feldStr.pop_front(); feld.second = feldStr.front(); // Feldwert felder[feld.first] = feld.second; // Paar speichern } return felder; // Abbildung Feld-Name -> Feld-Wert zurueck geben }
und jetzt noch der Code, wo ich die Methode nutzen möchte:
#include <iostream> #include <fstream> #include <cstdlib> #include <list> #include <map> #include "Artikel.h" #include "Werkzeug.h" using namespace std; int main() { string eingabe; getline(cin,eingabe); Werkzeug cgi; map <string, string> test = cgi.parseStream(eingabe); test["user_eingabe"] = cgi.searchReplace(test["user_eingabe"]); test["EingabeFeld"] = cgi.searchReplace(test["EingabeFeld"]); test["EingabeFeld1"] = cgi.searchReplace(test["EingabeFeld1"]); Artikel Wiki("Titel",test["EingabeFeld1"]); Wiki.printHeader(); cout << "<p>" << endl; cout << "<h3>CGI Analyse</h3>" << endl; cout << "<hr>" << endl; cout << "Die Elemente:<br> " << endl; cout << " Feld-A = " << test["EingabeFeld"] // Wert von Feld mit Namen Feld-A ausgeben << "<br>" << " Feld-B = " << test["EingabeFeld1"] // Wert von Feld mit Namen Feld-B ausgeben << endl; cout << "<p>" << endl; cout << "<hr>" << endl; cout << "</body></html>" << endl; cout << test["user_eingabe"]; cout << "<br><br><br><hr>"; cout << cgi.directory("../htdocs/",".htm"); //dir(); ofstream fout(test["EingabeFeld"].c_str()); fout << test["user_eingabe"]; fout.close(); }
Vielen Dank im Voraus
-
Du hast die Methoden split() und parseStream() zwar in der Definition der Klasse angegeben, aber in deiner Werkzeug.cpp stehen nur zwei globale Funktionen mit dem selben Namen.
(oder kurz: Du hast das Werkzeug:: bei der Definition vergessen)PS: Vielleicht übersehe ich ja etwas (bei deinem Code auch nicht verwunderlich), aber an welcher Stelle verwendest du eigentlich die Klassenmember _Zeichenkette, _searchstring,...?
-
ohhh man, natürlich. Naja sowas passiert halt als c++ Anfänger. Und das der Code unübersichtlich ist. Naja, mir egal, hauptsache es genügt später annähernd den Anforderungen des Profs
-
C Stoll wollte wohl eher auf das verwenden von c/c++ Code Tags statt einfachen code Tags hinweisen, sowie dass du etwas viel Code gepostet hast (manches haettest du ja wegstreichen koenen) das macht es den leuten hier schwieriger es zu lesen und ergo zu korrigieren.
-
@Shinja: Worauf ich mit meinem PS eigentlich hinauswollte war die Frage, warum das Ganze in eine Klasse verpackt wurde (theoretisch hätte auch eine Sammlung an freien Funktionen ausgereicht). Schon die Tatsache, daß der Compiler die beiden Funktionen problemlos compiliert hat, deutet auf einen Designfehler oder Verständnisproblem hin.
-
Naja, also laut Prof soll alles in Klassen und objektorientiert. Dann hat er uns noch Designregeln mitgegeben. Aber wie gesagt: als Anfänger ist es schwer überhaupt was auf die Beine zu stellen...