Verstehe eine Fehlermeldung von Visual Studio nicht. Bitte um Hilfe. Es geht um nicht aufgelöste Verweise



  • ifstream liegt im namespace std. Hast du das berücksichtigt?
    Poste mal die komplette init.h



  • //Funktionsdeklarationen
    void wortdateoOeffnen();
    void fuelleVector(ifstream& stream);
    void ausgabeVector();
    void zufallswort();
    void anzahl();
    

    namespace std; habe ich nur bei der init.cpp angebeben.



  • Wo sind die Include-Guards?
    Du must std:: vor ifstream schreiben.



  • Danke.
    Habe ich jetzt erledigt.

    Jetzt will der Funktionsaufruf in der menu.cpp aber einen Parameter mit übergeben bekommen.

    Ich der main.cpp musste ich nichts angeben.

    Die Funktion steht wie gesagt in der init.cpp

    void fuelleVector(ifstream& stream){
    	string buffer;
    	while(getline(stream, buffer)){
    		karten.push_back(buffer);
    	}	
    }
    

    Die Datei wird darüber in einer Funktion geöffnet:

    void wortdateoOeffnen(){
    
    	string Dateiort;
    
    	cout << "Bitte die Datei inklusive Pfad angeben" << endl;
    	//Text noch rot machen
    	cout << "ACHTUNG: Bei Windows bitte / (Slash) mit \ (Backslash) austauschen " << endl << endl ;
    	cout << "---> ";
    	cin >> Dateiort;
    	cout << endl;
    	cout << endl;
    
    	ifstream file(Dateiort);
    	if(file.is_open() != true){
    		//ROT
    		cout << "Datei konnte nicht geoeffnet werden, bitte geben Sie einen korrekten Pfad an" << endl;
    		wortdateoOeffnen();
    	}else{
    
    		cout << "Datei erfolgreich geoeffnet" << endl;
    	}	cout << endl;
    }
    

    Meinst du mit den Include Guards die #ifdef, #ifndef Anweisungen?



  • Der Compiler schaut sich immer nur eine einzige Übersetzungseinheit an. Du hast zwei Übersetzungseinheiten, ich mach das hier mal per cut&paste übersichtlicher:

    Einheit #1:

    #include <iostream>  // Das hier einzufügen wäre etwas unübersichtlich
    #include <string>
    
    void wortdateoOeffnen();
    void fuelleVector(ifstream& stream);
    void ausgabeVector();
    void zufallswort();
    void anzahl();
    
    int main()
    {
       // ...
    }
    

    Einheit #2:

    void fuelleVector(ifstream& stream){
        string buffer;
        while(getline(stream, buffer)){
            karten.push_back(buffer);
        }  
    }
    
    void wortdateoOeffnen(){
    
        string Dateiort;
    
        cout << "Bitte die Datei inklusive Pfad angeben" << endl;
        //Text noch rot machen
        cout << "ACHTUNG: Bei Windows bitte / (Slash) mit \ (Backslash) austauschen " << endl << endl ;
        cout << "---> ";
        cin >> Dateiort;
        cout << endl;
        cout << endl;
    
        ifstream file(Dateiort);
        if(file.is_open() != true){
            //ROT
            cout << "Datei konnte nicht geoeffnet werden, bitte geben Sie einen korrekten Pfad an" << endl;
            wortdateoOeffnen();
        }else{
    
            cout << "Datei erfolgreich geoeffnet" << endl;
        }   cout << endl;
    }
    
    // ....
    

    In Einheit #2 weiß der Compiler jetzt mit all den Typen dort nichts anzufangen, weil sie ihm nicht wie in Einheit #1 per includes bekannt gemacht wurden. (Edit: und das using namespace std; wird wohl auch fehlen in Einheit #2, ja)
    Edit #2: In Zeichenkettenliteralen ist es so, dass das \ eine Spezialzeichen-Einleitung darstellt, mit \\ drückt man dann das gedruckte "\" aus.

    Offenbar schluckt das Board hier in "" das erste \ Oo



  • Da hast du natürlich recht.
    Habe ich total vergessen.
    Alle header Dateien haben jetzt die Includes.
    Es lässt sich auch kompilieren.

    Leider erhalte muss ich immer noch einen Parameter angeben. Das musste ich in der main nicht, als noch dort alles drin stand.

    Ich machs mal so, poste den Code mal bei gist und zeige ihn hier:

    https://gist.github.com/4505232

    in der menu.cpp bei fuelleVector(); erwartet die Funktion ein Argument.

    Gruß



  • Und überrascht dich das? Du hast doch explizit einen Parameter deklariert, den musst du auch übergeben. Das kann vorher auch nicht anders gewesen sein. Nicht bei ansonsten gleichem Code.



  • Eine Funktion mit Argumenten braucht nunmal zwingend Argumente beim Aufruf (wenn man von default-Werten mal absieht), da ändert sich nichts dran, in welcher Datei sie definiert wird.
    Als du die Funktion aber im Header ohne Argumente deklariert hattest, verließ sich der Compiler darauf, dass der Linker die entsprechende Funktion in einer anderen Übersetzungseinheit definiert finden würde, deshalb gab es keine Compilier-Fehler sondern erst später die Linker-Fehler.

    Und bitte kein using namespace std; in Headern. Jede Übersetzungseinheit, die diesen Header verwenden möchte, hat dann die komplette Standardbibliothek im globalen Namensraum, was zu unschönen Namenskollisionen führen kann.



  • Ok habe ich verstanden.
    Werde using namespace std; in den Header Dateien nicht mehr verwenden.
    Kann mir denn einer bei den Parametern helfen?

    Ich weiß wirklich nicht, welche ich übergeben soll, da die Datei ja in der init.cpp geöffnet wird und dort auch der buffer erzeugt wird. In der menu.cpp ist ja nichts davon?!

    Wüsste nicht, was ich übergeben solle/könnte?!



  • Ja, da hast Du Recht, das ist mit der derzeitigen Aufteilung schlecht.
    Ich würde aus dem Bauch heraus folgendes vorschlagen:

    std::vector< ... > leseDaten( std::istream& quelle )
    {
    }
    
    std::vector< ... > leseDatenAusDatei( std::string name )
    {
        std::ifstream datei( name );
        return leseDaten( datei );
    }
    


  • Danke für den Tipp.
    Ich muss mal schauen ob ich damit klar komme.
    Hab in c++ noch nie mit Dateien einlesen/auslesen gearbeitet.

    Der Ansatz ist, die Datei direkt beim öffnen in den Vektor zu schieben? Und nicht erst in einen buffer und dann den buffer in den Vektor?



  • Der Ansatz ist, dass die Funktion, die die Datei öffnet auch das Auslesen anstößt. Die hat ja die Datei am Start und kann eine Referenz dazu an die Auslese-Routine weiterleiten (die genausogut auch aus einem stringstream oder von der Konsole lesen könnte).


Anmelden zum Antworten