Header und CPP Dateien?
-
Hi,
ich habe wieder ein Problem mit Visual Studio 2005 (habe davor etwas mit Borland C++ Builder programmiert):
Ich möchte bestimmte Funktionen auslagern in Header bzw. CPP Dateien.
Dazu habe ich folgene Funktionen geschrieben:stringElements.cpp
string strflip(string inValue) { string rev(inValue); unsigned int vlen = inValue.length(); unsigned int n = 0; while(vlen > 0) { rev[n] = inValue[vlen-1]; n++; vlen--; } return rev; } string generateRandomString(unsigned int num) { srand(time(0)); string possible("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:;-=(){}[]&/\|@€%!?.,_"); string random; unsigned short int loading = (num/25); cout << "\n Generating key"; cout << "\n\n 0% "; for(unsigned int n = 0; n < num; n++) { random = random + possible[rand()%possible.length()]; if (n % loading == 0) { cout << "|"; } } cout << " 100%\n"; return random; }stringElements.h
#include "stringElements.cpp"main.cpp
#pragma once #define WIN32_LEAN_AND_MEAN #include <tchar.h> #include <iostream> #include <fstream> #include <string> #include <ctime> #include "stringElements.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { // code return 0; }Visual Studio meldet beim kompilieren:
error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'strflip'
Weiß jemand warum?
-
Ich habe den Quellcode wie folgt verändert
stringElements.h
#ifndef __STRINGELEMENTS_H__ // mit diesen Präprozessordirektiven wirst du keinen Ärger bekommen, wenn du die Includedatei in mehrere .cpp Dateien einbindest. #define __STRINGELEMENTS_H__ #include <ctime> #include <string> #include <iostream> using namespace std; // Bekanntmachen der Funktionen string strflip(string inValue); string generateRandomString(unsigned int num); #endifstringElements.cpp
#include "stringElements.h" string strflip(string inValue) { string rev(inValue); // Warning wegen inkompatiblen Größen unsigned int vlen = inValue.length(); unsigned int n = 0; while(vlen > 0) { rev[n] = inValue[vlen-1]; n++; vlen--; } return rev; } string generateRandomString(unsigned int num) { // Warning wegen inkompatiblen Größen srand(time(0)); string possible("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:;-=(){}[]&/\\|@€%!?.,_"); // ein \ als Zeichen muss man mit \\ signalisieren, da \ ein Escapezeichen ist string random; unsigned short int loading = (num/25); cout << "\n Generating key"; cout << "\n\n 0% "; for(unsigned int n = 0; n < num; n++) { random = random + possible[rand()%possible.length()]; if (n % loading == 0) { cout << "|"; } } cout << " 100%\n"; return random; }main.cpp
#pragma once #define WIN32_LEAN_AND_MEAN #include <tchar.h> #include <iostream> #include <fstream> #include <string> #include <ctime> #include "stringElements.h" using namespace std; int main(int argc, char* argv[]) { // code return 0; }
-
Ich würd kein using namespace std; im Header machen, nur im .cpp
-
Wieso?
Was ist daran auszusetzen?
-
hola
vielleicht so:
stringElements.cpp
#include "StringElements.h" string strflip(string inValue) { string rev(inValue); unsigned int vlen = inValue.length(); unsigned int n = 0; while(vlen > 0) { rev[n] = inValue[vlen-1]; n++; vlen--; } return rev; } string generateRandomString(unsigned int num) { srand(time(0)); string possible("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:;-=(){}[]&/\|@€%!?.,_"); string random; unsigned short int loading = (num/25); cout << "\n Generating key"; cout << "\n\n 0% "; for(unsigned int n = 0; n < num; n++) { random = random + possible[rand()%possible.length()]; if (n % loading == 0) { cout << "|"; } } cout << " 100%\n"; return random; }stringElements.h
#include <string> #include <iostream> ... string strflip(string inValue); string generateRandomString(unsigned int num)main.cpp
#include "stringElements.h" ... int _tmain(int argc, _TCHAR* argv[]) { // code return 0; }Meep Meep
-
Vic schrieb:
Wieso?
Was ist daran auszusetzen?Du machst damit in jeder Datei, wo du den Header einbindest den Namensraum auf, und vielleicht ist das nicht immer gewollt. (Für den Fall dass du mal Zeug schreibst, dass von anderen verwendet wird)
-
Jedoch geht es irgendwie immernoch nicht:
stringElements.h
#ifndef __STRINGELEMENTS_H__ #define __STRINGELEMENTS_H__ String bStringFlip(String inValue); String bGenerateString(unsigned int inNum); #endifstringElements.cpp
#include "stringElements.h" String bStringFlip(String inValue) { string rev(inValue); unsigned int vlen = inValue.length(); unsigned int n = 0; while(vlen > 0) { rev[n] = inValue[vlen-1]; n++; vlen--; } return rev; } String bGenerateString(unsigned int inNum) { srand(time(0)); string possible("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:;-=(){}[]&/\|@€%!?.,_"); string random; unsigned int tmp = 0; unsigned short int loading = (inNum/25); cout << "\n Generating key"; cout << "\n\n 0% "; for(unsigned int n = 0; n < inNum; n++) { random = random + possible[rand()%possible.length()]; if (n % loading == 0) { cout << "|"; } } cout << " 100%\n"; return random; }stdafx.h
#pragma once #define WIN32_LEAN_AND_MEAN // Selten verwendete Teile der Windows-Header nicht einbinden. #include <tchar.h> #include <iostream> #include <fstream> #include <string> #include <ctime> #include "stringElements.h" using namespace std;main.cpp
#include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { // Code des Hauptprogramms system("pause"); return 0; }Fehlermeldung ist immernoch:
error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'bStringFlip'
-
weil der Bezeichner "String" nicht bekannt ist (der im Übrigen auch string heisst)
deshalb musst du in deiner stringelements.h auch #include <string> einfügen.
Jedoch wird der Compiler immernoch mekkern, weil sich die Klasse string im std Namensraum befindet.Deshalb habe ich auch immer using namepace std; in der Headerdatei reingeschrieben

Also entweder du schreibst jetzt vor jedem string in der .h ein std:: oder du nimmst den using namespace Befehl.
PS: Versuche die Warnings auch noch zu beheben, weil die sonst zu einem unerwarteten Ergebnis führen. (Beispiel: \\ für ein \ in deiner stringelements.cpp)
Achja, und persönlich finde ich die Lösung mit der stdafx.h nicht so toll. Jede Headerdatei sollte meiner Meinung nach die benötigten includes Aufweisen und nicht zentral in einer Datei. Ist aber jedem selbst überlassen.
Gruß
Vic
-
Ok, vielleicht besser nochmal kurz zusammengefasst:
stringElements.h
#ifndef STRINGELEMENTS_H //Was wollt ihr immer mit den vielen __ davor und dahinter... #define STRINGELEMENTS_H #include <string> std::string bStringFlip(std::string inValue); std::string bGenerateString(unsigned int inNum); #endif //STRINGELEMENTS_HstringElements.cpp
#include "stringElements.h" #include <string> //nicht unbedingt notwendig, aber was ich verwende incldue ich auch da wo ichs verwende using namespace std; //in cpp Dateien in Ordnung string bStringFlip(string inValue) { string rev(inValue); for(unsigned int i=0;i<inValue.length();++i) //bisschen umgeaendert, kann aber ruhig auch so gelassen werden wies war rev[i] = inValue[inValue.length()-i-1]; return rev; } string bGenerateString(unsigned int inNum) { //srand(time(0)); das sollte besser an die Anfang der main() string possible("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:;-=(){}[]&/\|@€%!?.,_"); string random; unsigned int tmp = 0; unsigned short int loading = (inNum/25); cout << "\n Generating key"; cout << "\n\n 0% "; for(unsigned int n = 0; n < inNum; n++) { random = random + possible[rand()%possible.length()]; if (n % loading == 0) cout << "|"; } cout << " 100%\n"; return random; }main.cpp
#include "stringElements.h" #include <ctime> //restliche includes die du brauchst using namespace std; int main(){ srand(time(0)); //Code deines Programmes system("pause"); //nicht portabel, schau mal in der KonsolenFAQ nach "Schliessen des Konsolenfenster verhindern" return 0; }Falls ich jetzt nichts vergessen habe sollte es jetzt funktionnieren. beachte dass deine Dateien alle im gleichen projekt enthalten sein muessen.