Frage zu header Datein



  • ÄH was ich versteh jetzt nur Bahnhof.



  • Stromberg schrieb:

    ÄH was ich versteh jetzt nur Bahnhof.

    Damit wollte er sagen, dass es bei ihm geht.

    Allerdings wissen wir immer noch nicht, was "son ganz komischer Error" ist.

    Übrigens ist von using-Direktiven in Headerdateien abzuraten.



  • MFK schrieb:

    Stromberg schrieb:

    ÄH was ich versteh jetzt nur Bahnhof.

    Damit wollte er sagen, dass es bei ihm geht.

    Allerdings wissen wir immer noch nicht, was "son ganz komischer Error" ist.

    Übrigens ist von using-Direktiven in Headerdateien abzuraten.

    Dito. Nja, ich dachte, vllt probierst Du's mal mit make und gcc - Vielleicht liegt's an der Compiler/Linker Einstellung (vllt auch mal Compiler angeben). Der Code ist imho allerdings etwas "irrsinnig", aber Dir geht's ja auch nicht um guten Code, sondern um das Verhalten beim Zusammenbauen. Dafuer braeuchte man allerdings ein paar mehr Zeilen der Fehlerausgabe. Vllt handelt es sich nur um eine "Warning" und kein "Error"?



  • Also ich poste mal alles jetzt rein, und wundert euch bitte nicht über mein Programm ich hab jetzt kein bock die cout stellen umzuschreiben.
    Eigentlich war das mit dem string in der header nur als Testzeile (erstmal) gedacht um zu schaun ob es geht und dann hätt ich es später im Programm anwenden können. Is jetzt glaub nicht so wichtig das ganze Programm zu posten aber ich machs trotzdem vll. hat das ja was mit dem Zusammenhang zu tun kp.

    //main
    #include "Bot_functions.h"
    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
        //###DAS IST DIE ZEILE UM DIE ES    EIGENTLICH GEHT###
        cout << b << endl;  //is nur eine Test Zeile gehört nachher natürlich nicht hier hin und auch nicht zum programm 
        string temp;
        cout << "***  'Assozialer Bot' made by Andy  ***\n\n\n";
    
        do
        {
            if (CheckWord(temp,25)!=all_right)
            {
                cout << "Unter welchem Nicknamen wollen sie sich mit dem Bot unterhalten?" << endl;
                cout << "(Namen " << "\x81" << "ber 25 Buchstaben sind nicht erlaubt) Eingabe:";
                GetString(temp,50);
                if (CheckWord(temp,25)!=all_right)
                {
                    cout << "\n### ERROR ###  >> ";
                    if (CheckWord(temp,25)==too_long)
                    cout << "Der Nickname hat " << "\x81" << "ber 25 Buchstaben du Matschbirne.\n" << endl;
                    else
                    cout << "Es ist noch kein Nickname eingegeben du Vollidiot.\n" << endl;
                }
    
            }
    
            if (CheckWord(temp,25)==all_right)
            {
                cout << "Hallo " << temp << endl;
            }
    
        }while(temp!="ende");
    
    	return 0;
    }
    
    //Bot_functions.h
    #ifndef BOT_FUNCTIONS_H_INCLUDED
    #define BOT_FUNCTIONS_H_INCLUDED
    
    #include <iostream>
    #include <string>
    using namespace std;
    
    string b="Hello World"; //is auch nur eine Testzeile ###DAS IST DIE ZEILE UM DIE ES EIGENTLICH GEHT###
    enum ERROR {too_long,no_characters,all_right};
    void GetString(string &s,int maxlength);
    ERROR CheckWord(const string &s,int maxlength);
    
    #endif // BOT_FUNCTIONS_H_INCLUDED
    
    //Bot_functions.cpp
    #include "Bot_functions.h"
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    void GetString(string &s,int maxlength)
    {
        char *temp=new char[maxlength+1];
        cin.getline(temp,maxlength);
        s=temp;
        delete []temp;
    }
    
    ERROR CheckWord(const string &s,int maxlength)
    {
        if (s.size()>maxlength)  //wenn string größer als die höchstlänge dann 1
        {
            return too_long;
        }
        else if (s.size()==0)    //wenn im string noch gar nichts drin steht 2
        {
            return no_characters;
        }
        else if (s.size()<=maxlength)   //wenn string die höchstlänge nicht überschreitet und was drin steht 3
        {
            return all_right;
        }
    }
    

    So es kommt dann folgender Error:

    -------------- Build: Debug in Bot ---------------
    Compiling: main.cpp
    Compiling: Bot_functions.cpp
    Bot_functions.cpp: In function ERROR CheckWord(const std::string&, int)': Bot_functions.cpp:21: warning: comparison between signed and unsigned integer expressions Bot_functions.cpp:29: warning: comparison between signed and unsigned integer expressions Bot_functions.cpp:33: warning: control reaches end of non-void function Linking console executable: .\\Bot.exe obj\\Debug\\Bot\_functions.o: In functionZSt17__verify_groupingPKcjRKSs':
    c:/mingw/bin/../lib/gcc/mingw32/3.4.4/../../../../include/c++/3.4.4/bits/locale_facets.tcc:2497: multiple definition of `b'
    obj\Debug\main.o:c:/mingw/bin/../lib/gcc/mingw32/3.4.4/../../../../include/c++/3.4.4/bits/locale_facets.tcc:2497: first defined here
    collect2: ld returned 1 exit status
    Process terminated with status 1 (0 minutes, 1 seconds)
    2 errors, 3 warnings

    Und hier ist die .tcc Datei die geöffnet wird, bzw. die Stelle wo der Cursor stehen bleibt weil das teil hätte sonst über 2000 Zeilen:

    //...........
         __news[0] = __olds[0];
    	      __mod = 1;
    	      ++__news;
    	    }
    	  // else Padding first.
    	}
          _Traits::assign(__news, __plen, __fill);
          _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod),
    		    __oldlen - __mod);
        }
    
      bool
      __verify_grouping(const char* __grouping, size_t __grouping_size,
    		    const string& __grouping_tmp)
      {   // <-- hier bleibt der Cursor stehen 
        const size_t __n = __grouping_tmp.size() - 1;
        const size_t __min = std::min(__n, __grouping_size - 1);
        size_t __i = __n;
        bool __test = true;
    
        // Parsed number groupings have to match the
        // numpunct::grouping string exactly, starting at the
        // right-most point of the parsed sequence of elements ...
        for (size_t __j = 0; __j < __min &
    //.................
    

    So und jetzt noch zu dem "using namespace std;" aha das ist also schlechter Stil (hab ich nicht gewusst), aber wie soll ich das den sonst machen weil 'string' braucht doch das "std". Soll ich dann std::string schreiben???
    Dankeschön schon mal im Voraus.



  • Stromberg schrieb:

    string b="Hello World"; //is auch nur eine Testzeile ###DAS IST DIE ZEILE UM DIE ES EIGENTLICH GEHT###
    

    Und genau diese Zeile ist auch das Problem. Du darfst in Headerdateien keine Variablen definieren, sonst bekommst du Probleme, wenn diese Headerdatei in mehr als einer Übersetzungseinheit landet.



  • Ehm, wenn ich mich recht erinnere, mußt du es so machen:

    // bla.h
    extern std::string b;
    
    // bla.cpp
    std::string b = "Hello World";
    


  • @Artchi thx es funktioniert mit dem extern.....mh was genau soll exytern aber jetzt bewirken??? Und geht es eigentlich nicht wenn ich den string dann einfach in der .cpp deklariere und insziniere und in der header gar nichts mache??? Müsst doch auch gehen oder?

    Und warum geht eigentlich das mit dem Enum dann:

    //Bot_functions.h
    enum ERROR {too_long,no_characters,all_right}; //Zeile 9
    

    Weil das ist doch eigentlich genauso wie ein Typ? Oder kann man sonst alle Typen problemlos in einer header deklarieren, außer strings? Oder muss ich z.B. wenn ich in einer header eine int Variable deklariere auch das mit dem extern machen und dann nochmal in einer .cpp deklarieren???
    Dankeschön schon mal im Voraus.



  • extern sagt einfach, das die Variable (also eine physikalische Instanz) sich in einer anderen Compile-Einheit (sprich cpp-Datei) befindet.

    Ob du extern benutzt, hängt davon ab, ob die Variable für andere zugreifbar sein soll. In Headers kommt ja nur das rein, was andere kennen sollen. Du kannst ja auch folgendes machen:

    // a.cpp
    class Bla
    {
    };
    
    void foo()
    {
       Bla b;
    }
    

    Ohne das Bla in einer Header drin ist!!! So ist class Bla halt nur in der Compile-Einheit a.cpp bekannt.

    Ehm, genau das gleiche mit deiner string-Variable. extern hat nichts mit strings zu tun. Geht mit allen Typen.

    Wenn Du string b; nirgends woanders brauchst, nimm es halt aus dem Header raus.

    Zu den enums: das sind ja nur Aufzählungen. Also nur Beschreibungen. Die werden nachher in Maschinencode einfach als Ganzzahlen zu sehen sein. Es sind ja keine Typen. Enums sind Ganzzahlen, die du der Einfachheit Namen vergibst. Der Compiler macht aus:

    enum { krass, cool, wow};
    

    ein:

    enum {0, 1, 2};
    

    das merkst du halt nicht. Ist vergleichbar mit Makros. Nur halt nicht für den Präprozessor, sondern den Compiler und somit viel sicherer und schöner.



  • Hmm? Natürlich sind enums Typen.



  • Was mach ich den jetzt schon wieder falsch?
    In meinem Buch steht das man das mit den "{ }" so machen darf, da is sogar ein Beispiel das wird es ganz genauso gemacht, nur der Typ is nicht string sondern int. Hm ich könnte es zwar alles in eine Zeile schreiben aber ich werde mein Feld natürlich später noch vergrößern. Also wie mach ich das den jetzt sonst sodas es geht?
    Dankeschön schon mal im Voraus.

    //topics of conversation of Bot.hpp
    #ifndef TOPICS_OF_CONVERSATION_OF_BOT_H_INCLUDED
    #define TOPICS_OF_CONVERSATION_OF_BOT_H_INCLUDED
    
    using namespace std;
    #include <string>
    
    extern string Saetze[3];
    
    #endif
    
    //topics of conversation of Bot.cpp
    #include <string>
    using namespace std;
    
    string Saetze[3]={ {"Eugen Roth"},
                       {"Hans Werner Olm"},
                       {"Stromberg"} };
    

    -------------- Build: Debug in Bot ---------------
    Compiling: topics of conversation of Bot.cpp
    topics of conversation of Bot.cpp:6: error: brace-enclosed initializer used to initialize std::string' topics of conversation of Bot.cpp:6: error: brace-enclosed initializer used to initializestd::string'
    topics of conversation of Bot.cpp:6: error: brace-enclosed initializer used to initialize `std::string'
    Process terminated with status 1 (0 minutes, 0 seconds)
    3 errors, 0 warnings



  • using namespace in Headern ist nicht nur schlechter Stil, sondern (wenn du nicht genau weißt, was du tust) eine unnötige Fehlerquelle. Schreib lieber die fünf Zeichen mehr und nimm std::.

    Zu deinem Problem: Diese Klammerschreibweise gilt nur für Arrays. std::string (der "innere" Typ) ist aber kein Array. Lass die inneren Klammern also weg, dann sollte es gehen.



  • .filmor schrieb:

    Zu deinem Problem: Diese Klammerschreibweise gilt nur für Arrays. std::string (der "innere" Typ) ist aber kein Array.

    Was allerdings nicht das Problem ist. std::string ist einfach kein "Aggregate". Denn nur dort und bei primitiven Typen ist diese Form der Initialisierung mit den geschweiften Klammern zulässig.



  • Okay, beim derzeitigen Stand halt nur bei Arrays und POD-Structs. Soviel ändert das nicht... 😉


Anmelden zum Antworten