Positionierung von #include <iostream> bei Header-Einbindung



  • hi,

    ich lerne gerade c++ und bin bei der aufteilung meines quellcodes auf zwei dateien auf ein problem gestoßen. in der einen datei ist die main funktion, in der anderen die definitionen meiner verwendeten funktionen. in der header datei befinden sich ja dann die prototypen.
    meine funktionen und die mainfunktion verwenden diverse libraries wie cctype, conio.h, iostream usw. ich habe zunächst in beiden quelldateien die headerdatei vor den verwendeten libraries eingebunden und bekam prompt einen fehler bei der kompilierung. dann habe ich irgendwann mal die headerdatei als letztes eingebunden und alles hat tadellos funktioniert. da habe ich mir noch gedacht, ok anscheinend müssen erst libraries eingebunden werden, die verwendet werden.
    Das komische war dann allerdings, dass ich noch ein bisschen rumgespielt habe und sich rausgestellt, dass nur die iostream library vor meinem header eingebunden werden muss, die anderen können danach folgen. das ist nun die sache die ich gar nicht verstehe und auch nirgends eine antwort gefunden habe...

    vielleicht hat ja jemand eine idee, warum dass so sein könnte!? wenn ich die iostream library im header includen lasse, geht ja alles sowieso. ist auch nicht richtig ein problem, mich würde dass wirklich nur mal interessieren ob jemand weiß woher das kommt...

    schonmal danke im voraus 🙂 ,

    orolindu


  • Mod

    Du machst in deinen Headern irgendwelchen Unfug. Es ist sehr schlechter Stil, wenn Header sich so verhalten wie deine. In aller Regel lässt sich dies auch vermeiden.



  • Include einfach in allen Headern (und Cpp-Files) die Dateien, die sie benötigen. Weiters solltest du Include-Guards verwenden, um Merhfachincludes zu verhindern.



  • Ich möchte jetzt nicht undankbar erscheinen, aber inwiefern soll mir diese Antwort (die Erste) denn weiterhelfen? Ich bin nunmal gerade dabei, diese Programmiersprache zu lernen und dass ich dann noch nicht alles beherrsche, ist wohl klar. Ich wollte einfach nur wissen, ob jemand eine Idee hat, woher dieses Problem kommen könnte. Wenn sich dies in aller Regel vermeiden lässt, wäre auch ein Hinweis nett gewesen, wie.

    Ich dachte dies wäre ein Forum, in dem einem geholfen wird und nicht im allerersten Beitrag direkt Vorwürfe gemacht werden. Ich sage ja nichts gegen Kritik. Wenn mich jemand korrigiert und mir bessere Alternativen aufzeigt, ist das ja gut, dann lerne ich auch was. Aber eine Antwort wie die Erste nützt niemandem etwas und sorgt nur für schlechte Stimmung.



  • orolindo schrieb:

    ... bekam prompt einen fehler ...

    Dann poste ihn doch einfach mal 🙄

    Meine Vermutung:
    Du verwendest in irgendeinem deiner Header etwas aus iostream ohne dass
    dieser den include beinhaltet...

    Dadurch dass der include vor deinem Header steht, findet er ihn dann auch
    für deinen Header.

    Gruß,
    XSpille


  • Mod

    orolindu schrieb:

    Ich möchte jetzt nicht undankbar erscheinen, aber inwiefern soll mir diese Antwort (die Erste) denn weiterhelfen? Ich bin nunmal gerade dabei, diese Programmiersprache zu lernen und dass ich dann noch nicht alles beherrsche, ist wohl klar. Ich wollte einfach nur wissen, ob jemand eine Idee hat, woher dieses Problem kommen könnte. Wenn sich dies in aller Regel vermeiden lässt, wäre auch ein Hinweis nett gewesen, wie.

    Wie soll man dir denn helfen? Wir wissen nur, du hast einen Fehler. nicht einmal welchen, geschweige denn deinen Code. Man kann daher nur sagen, dass du einen Fehler gemacht hast.



  • Der Quellcode und die Fehlermeldung würden schon helfen. Ich tippe auf #include <windows.h> ggf. in Verbidung mit #include <algorithm> o.ä.



  • also mein Quellcode sieht so aus (wie gesagt bin Anfänger, ist also ein recht banales Programm):

    Also hier zunächst meine Header-Datei:

    // Projekt AfA_test; Datei afa.h
    // Funktionsprototypen und Strukturdeklaration
    
    #include <iostream>
    #ifndef data  // verhindert, dass Struktur und Konstante zweimal festgelegt werden
    #define data 
    	struct ausgabefeldT {double afa, restwert; int jahr;};
    	extern const int feld_max;
    #endif
    //
    //
    void linear(ausgabefeldT *pT, double wert, int i);
    void degressiv(ausgabefeldT *pT, double wert, int i);
    void digital(ausgabefeldT *pT, double wert, int i);
    void werte_eingeben(double& a, int& b);
    void weiter_machen(char& weiter, char& neu);
    void ausgabe(ausgabefeldT *pT, int i);
    void speichern(ausgabefeldT *pT, int i);
    

    Dann die Main-Funktion:

    // Projekt AfA_test; Datei afamain.cpp
    //Enthält Mainfunktion - Übungsprogramm zur Berechnung einer Abschreibung
    #include "afa1.h"
    
    using namespace std;
    
    int main() {
    
    	const int feld_max = 50;
    	ausgabefeldT Tabelle[feld_max], *pTab = Tabelle;
    	enum wahlT {menu, lin, deg, dig};
    	int n = 1, auswahl;
    	double zeitwert = 0;
    	char geht_weiter = 'J', ist_neu = 'J';		// Anfängliche Werte, um in die while-Schleifen einzusteigen
    	char * text[] = {"Methode waehlen: 1-Linear 2-Degressiv 3-Digital : ", 
    					 "\nLineare Methode \n\n",
    					 "\nDegressive Methode \n\n",
    					 "\nDigitale Methode \n\n"};
    	while (geht_weiter != 'N') {
    		system("cls");
    		if (ist_neu != 'N') werte_eingeben(zeitwert, n);
    		cout << endl << text[menu];
    		auswahl = 0;
    		while (auswahl < 1 || auswahl > 3) cin >> auswahl;
    		switch (auswahl) {						// Wahl der Berechnungsart, entsprechende Funktion angewandt
    			case 1 :	cout << text[lin];
    						linear(pTab, zeitwert, n);
    						break;
    			case 2 :	cout << text[deg];
    						degressiv(pTab, zeitwert, n);
    						break;
    			case 3 :	cout << text[dig];
    						digital(pTab, zeitwert, n);
    						break;
    		}
    	ausgabe(pTab, n);
    	weiter_machen(geht_weiter, ist_neu); // Wahl, ob nochmal gerechet werden soll
    
    	}
    
    	return 0;
    
    }
    

    und halt dann die Funktionendatei:

    // Projekt AfA_test; Datei afafunc.cpp
    //Enthält Implementationen der Funktionen
    #include <cctype>
    #include <conio.h>
    #include <iomanip>
    #include <fstream>
    #include "afa1.h"
    using namespace std;
    
    void werte_eingeben (double& a_wert, int& dauer) {
    	cout << "Hoehe des Beschaffungswerts : ";
    	do cin >> a_wert; while (a_wert < 1.0 || a_wert > 1E9); // Eingrenzung des Wertebereichs
    	cout << endl << "Dauer der Abschreibung : ";
    	do cin >> dauer; while (dauer < 1 || dauer > 50);		// Eingrenzung des Wertebereichs
    };
    void weiter_machen(char& weiter, char& neu) {
    	cout << endl << "Neue Berechnung? (j/n) : ";
    	do {
    		weiter = _getch();
    		weiter = toupper(weiter);							// So gilt entweder j oderJ, n oder N
    	} while (weiter != 'J' && weiter != 'N');
    	cout << endl;
    	if (weiter == 'J') {
    		cout << "Sollen neue Werte eingegeben werden? (j/n) : ";
    		do {
    			neu = _getch();
    			neu = toupper(neu);
    		} while (neu != 'J' && neu != 'N');
    		cout << endl;
    	}
    };
    void linear(ausgabefeldT *pT, double wert, int i) {
    	double afa_lin;
    	afa_lin = wert / i;
    	for (int k = 0; k < i; k++) {
    		(pT+k) -> afa = afa_lin;
    		(pT+k) -> jahr = k + 1;
    		(pT+k) -> restwert = wert -= afa_lin;
    	}
    
    };
    void degressiv(ausgabefeldT *pT, double wert, int i) {
    	double afa_deg;
    	for (int k = 0; k < i; k++) {
    		(pT+k) -> afa = afa_deg = (2 * wert) / i;
    		(pT+k) -> jahr = k + 1;
    		(pT+k) -> restwert = wert -= afa_deg;
    	}
    };
    void digital(ausgabefeldT *pT, double wert, int i) {
    	double afa_dig;
    	int afa_rechenwert = i*(i+1)/2;
    	for (int k = 0; k < i; k++) {
    		(pT+k) -> afa = afa_dig = (i-k)/(static_cast <double> (afa_rechenwert))*wert;
    		(pT+k) -> jahr = k + 1;
    		(pT+k) -> restwert = wert -= afa_dig;
    	}
    };
    void ausgabe (ausgabefeldT *pT, int i) {
    	int k;
    	cout.setf(ios::left, ios::adjustfield);
    	cout.setf(ios::fixed, ios::floatfield);
    	cout.precision(2);
    	cout << setw(6) << "Jahr" << setw(12) << "Afa" << setw(12) << "Restwert" << endl << endl;
    	for (k = 0; k < i; k++) {
    		cout << setw(6) << (pT+k) -> jahr << setw(12) << (pT+k) -> afa << setw(12) << (pT+k) -> restwert << endl;
    	}
    };
    

    Das ist jetzt so, wie alles Funktioniert. Wenn ich jetzt allerdings iostream in den beiden .cpp Dateien icluden lasse und zwar nach der Einbindung von "afa1.h", dann kommt der Fehler

    Fehler	1	error C2059: Syntaxfehler: ')'	d:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring	1500	1	AfA_test
    Fehler	2	error C2334: Unerwartete(s) Token vor '{'; sichtbarer Funktionstext wird übersprungen	d:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring	1501	1	AfA_test
    Fehler	3	error C2059: Syntaxfehler: ')'	d:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring	1500	1	AfA_test
    Fehler	4	error C2334: Unerwartete(s) Token vor '{'; sichtbarer Funktionstext wird übersprungen	d:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring	1501	1	AfA_test
    

    Ich weiß, dass manche Sachen vielleicht etwas umständlich sind, ich wollt aber vieles nochmal üben. Auch weiß ich, dass ich nicht sonderlich gut dokumentiert habe.
    An sich ist das jetzt für mich auch nicht so das Problem, ich machs dann einfach anders. Mich würde einfachn ur interessieren warum das so ist, um vielleicht das Thema ein bisschen besser zu überblicken.

    Achso, sollte ich wenn ich den iostream in den .cpp dateien includen lasse wieder so was wie eine #ifndef abfrage starten, damit die bibliothek nicht zweimal eingebunden wird?

    grüße



  • orolindu schrieb:

    Achso, sollte ich wenn ich den iostream in den .cpp dateien includen lasse wieder so was wie eine #ifndef abfrage starten, damit die bibliothek nicht zweimal eingebunden wird?

    Nein, solltest du nicht. Dazu gibts include-guards (google hilft weiter, falls dir das nichts sagt), die genau das tun.

    Dein #define in dem header ist sehr unschön - was willst du damit erreichen? Vielleicht sind include-guards genau das, was für deinen Header fehlt, dann ist das Konstrukt auch nicht nötig 🙂



  • Das ist der Übeltäter:

    #define data
    

    Per Konvention sollte man Defines *immer* nur in Großbuchstaben schreiben.



  • orolindu schrieb:

    #ifndef data  // verhindert, dass Struktur und Konstante zweimal festgelegt werden
    #define data
    

    gefährlich.
    Nimm statt data lieber AFA_H oder AFA_H_INCLUDED oder AFA_H_INCLUDED_UUIDF8AEF4AB556043F3A638C33101BA954F.



  • Gut, hab es bei mir zu #define AFA_H umgeändert.
    Ich habe auch mal include-guards gegooglet, aber alles was ich gefunden habe sah so ziemlich nach dem aus, was ich auch gemacht habe. Sollte ich #include <iostream> eventuell auch noch in den include guard (wenn es denn tatsächlich einer ist) packen?
    Naja wenn ich recht drüber nachdenke macht das ja alleine vom namen her schon sinn^^.

    danke für die tips!!

    grüße



  • orolindu schrieb:

    Gut, hab es bei mir zu #define AFA_H umgeändert.
    Ich habe auch mal include-guards gegooglet, aber alles was ich gefunden habe sah so ziemlich nach dem aus, was ich auch gemacht habe. Sollte ich #include <iostream> eventuell auch noch in den include guard (wenn es denn tatsächlich einer ist) packen?
    Naja wenn ich recht drüber nachdenke macht das ja alleine vom namen her schon sinn^^.

    danke für die tips!!

    grüße

    Ja, man packt es rein.
    Aber ist nicht nötig.
    <iostream> hat auch selber einen includeguard, der dafür sorgt, daß man ihn auch mehrmals inklidieren kann, ohne daß es zu fehlern kommt.

    DEIN includeguard macht nur, da0 DEINE headerdatei mehrmals inklidiert werden kann, ohne daß es deshalb zu fehlern kommt.

    Schubse noch Deine Funktionsdeklarationen rein. Auch nicht notwendig, aber üblich.


Anmelden zum Antworten