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);
    
    #endif
    

    stringElements.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);
    
    #endif
    

    stringElements.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_H
    

    stringElements.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.


Anmelden zum Antworten