C++ und Exception-Handling einbauen...

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

C++ und Exception-Handling einbauen...

Beitrag von Duff » 20.04.2009 17:28:01

Hallo,

komme mal wieder nicht bei einer Änderung in C++ weiter....

Ich habe ein Programm, dass 2 Parameter erwartet. Der erste Parameter ist der einzulesende File und der zweite Parameter ist der auszugebende File. Der erste File wird durch Eingabe eines Schlüssels xor-Verknüpft und im zweiten File gespeichert. Um den zweiten File wieder zu entschlüsseln, muss man diesen als ersten Parameter angeben und wieder den gleichen Schlüssel eingeben.

Habe bisher folgenden Code erstellt:

Code: Alles auswählen

// xor.h
#ifndef _XOR_H_
#define _XOR_H_
#include <iostream>
#include <string>
using namespace std;

class Daten {
public:
	Daten();
	~Daten();
	// Zeichenweise kopieren
	void copyChar4Char( ifstream& istream, ofstream& ostream, string s);
private:
	char* istream;
	char* ostream;
	string schluessel;
};
#endif

Code: Alles auswählen

// xor.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "xor.h"
using namespace std;

Daten::Daten() {
	cout << "Konstruktor" << endl;
}
Daten::~Daten() {
	cout << "Destruktor" << endl;
}

// Zeichenweise kopieren
void Daten::copyChar4Char( ifstream& istream, ofstream& ostream, string schluessel) {
	char ch;
	int i=0;	// Zaehler fuer den Schluessel
	cout <<"Bitte Schluessel eingeben: " ; getline(cin,schluessel);
	int schluessellaenge=schluessel.size();	// best. die Anzahl der Zeichen von schluessel
	cout << schluessel << endl;

	while(istream.get(ch)) {
		if(istream.fail()) {
			cout << "Unerwarteter Lesefehler!" << endl;
			break;
		}
		//ostream.put(ch);
		ostream.put(ch ^ schluessel[i]);
		if(ostream.fail()) {
			cout << "Unerwarteter Lesefehler!" << endl;
			break;
		}
		i++;
		if(i>=schluessellaenge)
			i=0;
	}
	cout << endl;
}
Hauptprogramm

Code: Alles auswählen

// main_xor.cpp
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
#include "xor.h"
using namespace std;

int main(int argc, char** argv) {
   if ((1==argc) || (argc<3)) {
      cerr << "Usage: " << argv[0] << " <InputFile> <OutputFile>" << endl;
      exit(1);
   }
   if (3==argc) {
   	ifstream f1(argv[1], ios::out|ios::binary|ios::in);
   	ofstream f2(argv[2]);
   	if( f1.is_open() != true ) {
  			cerr << "Konnte Datei " << argv[1] << " nicht öffnen!" << endl;
     		 return 1;
   	}
   	if( f2.is_open() != true ) {
   		cerr << "Konnte Datei " << argv[2] << " nicht öffnen!" << endl;
      	return 1;
   	}
		// Zeichenweise einlesen und verschluessel wieder ausgeben
		string s;
		Daten daten;
		daten.copyChar4Char(f1,f2,s);
		f1.close();
		f2.close();
	}

	return 0;
}
Beispiel einer Programmausführung:

Code: Alles auswählen

daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ ./main_xor 
Usage: ./main_xor <InputFile> <OutputFile>
daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ ./main_xor xor.cpp /tmp/verschluesselt.txt
Konstruktor
Bitte Schluessel eingeben: Duff
Duff

Destruktor
daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ file /tmp/verschluesselt.txt 
/tmp/verschluesselt.txt: data
daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ less /tmp/verschluesselt.txt 
"/tmp/verschluesselt.txt" may be a binary file.  See it anyway? 
daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ ./main_xor /tmp/verschluesselt.txt /tmp/entschluesselt.txt
Konstruktor
Bitte Schluessel eingeben: Duff
Duff

Destruktor
daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ cat /tmp/entschluesselt.txt
// xor.cpp
#include <iostream>
....
Nun würde ich das Programm gerne dahingend erweitern, dass ich Exception mit try und catch abfangen kann.
Allerdings bekomme ich es noch nicht hin, da ich nicht genau weiß, wie ich am besten vorgehe...


Danke & Gruß,
Daniel
Oh, yeah!

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 20.04.2009 18:30:53

Also ich schreib jetzt einfach mal ein paar Sachen hin... ;)

1. Exceptions

Was willst du da genau? Eventuell von jemandem geworfene Exceptions händeln oder selbst Exceptions verwenden? Soweit ich weiss werfen die meisten I/O Operationen in C++ erst mal keine Exceptions, du kannst das aber Anschalten für einige Events mittels ifstream->exceptions($flags).

Exceptions sind in erster Linie kein Selbstzweck, sondern dienen vor allem dazu Fehler an einer anderen Stelle im Programm zu händeln als dort wo sie auftreten. Dies könnte hier z.B. so laufen dass du die Fehlermeldung wenn du einen Lesefehler kriegst nicht direkt in copyChar4Char ausgeben möchtest sondern sonstwo.

Dazu könntest du dann z.B. das hier einfügen in copyChar4Char und das entsprechende Abfragen von fail() entfernen:

Code: Alles auswählen

istream->exceptions(ifstream::failbit);
Dann baust du einen try/catch Block um den Aufruf von copyChar4Char herum und gibts dort die entsprechende Fehlermeldung aus.

Vorteil eines solchen Vorgehens ist die Trennung des Algorithmus (das Verschlüsseln) vom User-Interface (z.B. könntest du die Fehlermeldung ja auch in einem Popup Fenster ausgeben lassen...).

In so einem kleine Programm macht das aber auch noch alles nicht soo viel Sinn. Man passt Sinnvollerweise die Komplexität der verwendeten Werkzeuge (Exceptions vs. Direktabfrage des Stream-Status) der Programmkomplexität an...

Grundsätzlich ist I/O mit Streams in C++ aber was vom übleren was Error-Handling angeht, da hast du dir das richtige Problem ausgesucht ;)
(Was jetzt nicht nur der Fehler von C++ ist; Date(ie)n lesen ist etwas vom mühsamsten überhaupt was Errorhandling angeht, weil so viel falsch sein kann in den Daten die man reinkriegt

2.

Code: Alles auswählen

if ((1==argc) || (argc<3)) {
Also erstens ist das doppelt gemoppelt weil argc == 1 ein Spezialfall von argc < 3 ist und überhaupt möchtest du wohl lieber sowas; damit passiert in jedem Fall etwas. Bei deinem Code wird z.B. argc > 3 nicht behandelt.

Code: Alles auswählen

if (argc != 3) {
  exit(1);
}
else { /* argc == 3 */

}
3.

Code: Alles auswählen

      f1.close();
      f2.close();
Das ist nett, aber in C++ nicht zwingend weil die lokalen Variablen f1 und f2 eh gleich nacher aus dem Scope rausfallen (schliessende } ) und gelöscht werden - deren Destruktor führt von selber die close()-Operation aus.

Ist natürlich durchaus konsequent wenn du das immer machst, und vielleicht auch leichter verständlich aber nicht nötig.

4. Es gibt eigentlich keinen Grund copyChar4Char zu einer Member-Funktion der Klasse Daten zu machen. Die Funktion greift ja auf keine der Membervariablen zu. Das ist natürlich eine Stilfrage - aber in C++ würde man für so etwas eher einen Namespace benutzen und die Funktion dort einfach so reinschreiben:

Code: Alles auswählen

namespace blabla {
  class Daten {
    ...
  }

  void copyChar4Char( ifstream& istream, ofstream& ostream, string schluessel) {
    ...
  }
}
Zugegebenermassen läuft das schlussendlich auf dasselbe hinaus - ob man jetzt Klassen oder Namespaces für die Gruppierung von Funktionalität benutzt, es ist aber sicher gut wenn man seine Klassen nicht zu sehr mit Funktionalität überlädt.

[Nachtrag]Es fällt mir erst jetzt auf - aber die Daten-Klasse ist eigentlich komplett überflüssig; die beiden istream/ostream Members benutzt du ja gar nicht, oder? Genausowenig wie den String "schluessel".

Im Übrigen ist der Variablenname für den Schlüssel im Header und in der Implementierung verschieden - auch seeehr verwirrend!
[/Nachtrag]

5.

Code: Alles auswählen

 void Daten::copyChar4Char( ifstream& istream, ofstream& ostream, string schluessel) 
Eigentlich solltest du hier pass-by-reference machen für den String:

Code: Alles auswählen

 void Daten::copyChar4Char( ifstream& istream, ofstream& ostream, const string& schluessel) 
Den restlichen Code musst du dafür nicht ändern. Bei deinem Code wird beim Aufruf von copyChar4Char eine Kopie des Schlüssels im Speicher erstellt; es reicht wenn du eine Referenz darauf übergibst. Wenn du die Const machst stellst du auch sicher dass innerhalb von copyChar4Char der Schlüssel nicht verändert wird (und - fast noch wichtiger - du ermöglichst auch dass wirklich konstante Strings an die Funktion übergeben werden können; z.B. solche die du von einer anderen Funktion schon als const zurückgekriegt hast...)

6.

Code: Alles auswählen

if( f1.is_open() != true )
Naja, kürzer und imo leserlicher wäre:

Code: Alles auswählen

if( ! f1.is_open() )
7. Das

Code: Alles auswählen

using namespace std;
im Header xor.h würde ich in einem "richtigen" Programm eher unterlassen, das wirkt sich nämlich auch gleich direkt auf alle Dateien aus die das Header includen. Was den ganzen Zweck von Namespaces negiert ;)
Du siehst schon - C++ ist eine umständliche Sprache.

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 20.04.2009 19:50:14

Erstmal Danke für die vielen Verbesserungsvorschläge und die ausführlichen Erklärungen!

Muss mir deine Vorschläge nochmals durchlesen und schauen, wie ich das gesamte Programm nun besser implementieren kann.
Ich überlege auch noch, die Überprüfungen eventuell in eine kleine Funktion zu packen, wie z.B.

Code: Alles auswählen

      if( f1.is_open() != true ) {
           cerr << "Konnte Datei " << argv[1] << " nicht öffnen!" << endl;
            return 1;
      }
      if( f2.is_open() != true ) {
         cerr << "Konnte Datei " << argv[2] << " nicht öffnen!" << endl;
         return 1;
      }
Mit den Exceptions würde ich gerne ermitteln können, warum z.B. eine Datei nicht geöffnet werden konnte (file existiert nicht, Berechtigungen falsch, etc.). Sowas müsste doch auch möglich sein.

Wie würdest du dieses Programm denn aufbauen?
Mit oder ohne header-Datei?
Oh, yeah!

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 20.04.2009 20:52:49

Duff hat geschrieben: Ich überlege auch noch, die Überprüfungen eventuell in eine kleine Funktion zu packen, wie z.B.
...
Mit den Exceptions würde ich gerne ermitteln können, warum z.B. eine Datei nicht geöffnet werden konnte (file existiert nicht, Berechtigungen falsch, etc.). Sowas müsste doch auch möglich sein.
Mit den Exceptions die ifstream wirft findest du die Sachen wie Existenz der Datei und Benutzerrechte erst mal nicht heraus. Nur dass das Öffnen fehlschlug.

Existenz der Datei kannst du z.B. mit der Boost Filesystem Bibliothek überprüfen:

Code: Alles auswählen

#include "boost/filesystem.hpp"

#include <iostream>
#include <fstream>
using namespace std;

int main () {
  string filename("/tmp/file");

  if (!boost::filesystem::exists(filename))
    std::cout << "File does not exist" << std::endl;


  ifstream file;
  file.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
  try {
    file.open(filename.data());
    //while (!file.eof()) file.get();
  }
  catch (exception& e) {
    cout << e.what() << endl;
  }
  
  return 0;
}
Zu kompilieren mit sowas in die Richtung:

Code: Alles auswählen

g++ -I/usr/include/boost-1_37/ -lboost_filesystem-mt-1_37 test.cpp -o test
Das Programm schaltet auch gleich alle möglichen Exception von ifstream an; allerdings sind das nicht soo viele Nützliche. Die Dateiberechtigungen kriegst du weder von Boost noch von der STL, da musst du wennschon schon mit den Unix-Linux-Libc Funktionen dahinter... (Da fällt mir jetzt gerade auch nichts einfaches, bequemes, C++-Mässiges ein, hab ich noch nie gemacht...)

Wie das mit den Dateirechten C ginge (und entsprechend mit C++ genau gleich) steht z.B. hier.

Kleine Nebenbemerkung: Natürlich hast du damit potentiell race-conditions, wenn du das zuerst prüfst und dann die Datei öffenst (jemand könnte die ja in Zwischenzeit löschen oder die Rechte ändern; oder umgekehrt wenn du die Sachen erst prüfst wenn das Lesen fehlgeschlagen ist)
Wie würdest du dieses Programm denn aufbauen?
Mit oder ohne header-Datei?
Erst mal alles in einer Datei, solange es einigermassen klein bleibt. In mehrere Dateien aufteilen kann man später immer noch, das kostet aber am Anfang nur Zeit und zwingt dich dazu viel Zeugs zu schreiben das recht unwichtig ist (die Header...)

Ich denke eine Aufteilung wie du sie angedacht hast - also:

Code: Alles auswählen

void copyChar4Char(istream& istream, ostream& ostream, const string& schluessel);
void copyChar4Char(const std::string& input_file, const std::string& output_file, const string& schluessel);
Wobei die zweite Methode von main() aufgerufen wird, die Streams öffnet und Fehlerhandling diesbezüglich macht und die erste Methode praktisch so bleibt wie sie schon ist (eventuell mit Exceptions werfen die du dann in der zweiten Methode auffängst).

Bemerke dass die erste Methode istream/ostream und nicht ifstream objekte als Parameter erhält - d.h. sie funktioniert z.B. auch mit istringstream Objekten und nicht nur ausschliesslich mit Datei-I/O via ifstream.

Nochwas: Ich würde es mir angewöhnen konsequent Funktions- und Argumentnamen und am besten gleich auch Kommentare in einer einzigen Sprache zu verwenden. Die wäre dann möglichst Englisch. Irgendwann hast du sonst dann das totale Chaos (hatte ich auch schon, mit drei Sprachen..., macht keinen Spass)

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 21.04.2009 11:02:09

Danke, aber ich befürchte, dass du mich jetzt ein wenig abgehängt hast.
Blicke ehrlich gesagt nicht mehr wirklich durch.

Habe bisher versucht alles so umzuschreiben:

Code: Alles auswählen

// xor_new.cpp
#include "boost/filesystem.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;

// Zeichenweise kopieren
void copyChar4Char( const string& input_file, const string& output_file, string& schluessel);

bool fileExist(const string& filename);

int main(int argc, char** argv) {
	if (argc != 3) {
		cerr << "Usage: " << argv[0] << " <InputFile> <OutputFile>" << endl;
  		exit(1);
	}
	else { /* argc == 3 */
		string input_file	=argv[1];
		string output_file=argv[2];
		string s;

		if( !fileExist(input_file))
			return 1;

		//ifstream input_file	= input_file;
  		ifstream file;
  		file.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
  		try {
    		file.open(input_file.data());
    		//while (!file.eof()) file.get();
    		copyChar4Char(input_file,output_file,s);
    	}
      catch (exception& e) {
      	cout << e.what() << endl;
    	}
	}

}

// Zeichenweise kopieren
void copyChar4Char( const string& input_file, const string& output_file, string& schluessel) {
	char ch;
	int i=0;	// Zaehler fuer den Schluessel
	cout <<"Bitte Schluessel eingeben: " ; getline(cin,schluessel);
	int schluessellaenge=schluessel.size();	// best. die Anzahl der Zeichen von schluessel
	cout << schluessel << endl;
	while(input_file.get(ch)) {
		if(input_file.fail()) {
			cout << "Unerwarteter Lesefehler!" << endl;
			break;
		}
		//output_file.put(ch);
		output_file.put(ch ^ schluessel[i]);
		if(output_file.fail()) {
			cout << "Unerwarteter Lesefehler!" << endl;
			break;
		}
		i++;
		if(i>=schluessellaenge)
			i=0;
	}
	cout << endl;
}

bool fileExist(const string& filename) {
	if (!boost::filesystem::exists(filename)) {
  		//cout << "File " << filename " does not exist" << endl;
  		cout << "File " << filename << " does not exist!" << endl;
		return false;
	} else {
		return true;
	}
}
Aber sobald ich die Funktion zum Kopieren der Zeichen verwende, geht nichts mehr.

Code: Alles auswählen

daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ g++ -Wall -o main_xor_new xor_new.cpp -lboost_filesystem
xor_new.cpp: In function ‘void copyChar4Char(const std::string&, const std::string&, std::string&)’:
xor_new.cpp:49: error: ‘const struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ has no member named ‘get’
xor_new.cpp:50: error: ‘const struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ has no member named ‘fail’
xor_new.cpp:55: error: ‘const struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ has no member named ‘put’
xor_new.cpp:56: error: ‘const struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ has no member named ‘fail’
Oh, yeah!

Benutzeravatar
armin
Beiträge: 2682
Registriert: 17.03.2005 11:49:14

Re: C++ und Exception-Handling einbauen...

Beitrag von armin » 21.04.2009 13:10:31

Code: Alles auswählen

const string& input_file, const string& output_file
Du versuchst gerade Methoden für Datei-Streams auf Strings auszuführen. Du willst deiner copy-methode wohl eher 'file' als 'input_file' übergeben.
Formerly known as Trigger.
HP 8510p - Debian Sid
Mitglied des Debian-KDE-Teams

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 21.04.2009 15:53:13

Puh...

Ich habe es jetzt bisher mal so abgeändert und es funktioniert soweit auch.

Code: Alles auswählen

// xor_new.cpp
#include "boost/filesystem.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;

// Zeichenweise kopieren
void copyChar4Char( ifstream& istream, const string& input_file, ofstream& ostream, const string& output_file, string& schluessel );

bool fileExist(const string& filename);

int main(int argc, char** argv) {
	if (argc != 3) {
		cerr << "Usage: " << argv[0] << " <InputFile> <OutputFile>" << endl;
  		exit(1);
	}
	else { /* argc == 3 */
		string input_file	=argv[1];
		string output_file=argv[2];
		string s;

		if( !fileExist(input_file))
			return 1;

  		ifstream f1;
		ofstream f2( argv[2] );
  		f1.exceptions ( ifstream::eofbit | ifstream::failbit | ifstream::badbit );
  		try {
    		f1.open(input_file.data());
    		copyChar4Char(f1,input_file,f2,argv[2],s);
    	}
      catch (exception& e) {
      	cout << "Exception: " << e.what() << endl;
    	}
	}

}

// Zeichenweise kopieren
void copyChar4Char( ifstream& istream, const string& input_file, ofstream& ostream, const string& output_file, string& schluessel) {
	char ch;
	int i=0;	// Zaehler fuer den Schluessel
	cout <<"Bitte Schluessel eingeben: " ; getline(cin,schluessel);
	int schluessellaenge=schluessel.size();	// best. die Anzahl der Zeichen von schluessel
	
	while( istream.get(ch) ) {
		cout << ch;
		ostream.put(ch ^ schluessel[i]);
		i++;
		if(i>=schluessellaenge)
			i=0;
	}
	cout << endl;
}

bool fileExist(const string& filename) {
	if (!boost::filesystem::exists(filename)) {
  		//cout << "File " << filename " does not exist" << endl;
  		cout << "File " << filename << " does not exist!" << endl;
		return false;
	} else {
		return true;
	}
}
Aber wieso kann ich an ofstream f2 nicht den Stringnamen output_file übergeben?
Was muss ich ändern, weil man es so nicht in C++ programmiert?
Oh, yeah!

Milbret
Beiträge: 827
Registriert: 26.05.2008 12:04:54
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Nörten-Hardenberg
Kontaktdaten:

Re: C++ und Exception-Handling einbauen...

Beitrag von Milbret » 21.04.2009 18:28:52

hallo,
hab jetzt nicht alles gelesen ;)
Aber zu deinen letzten Fragen.

Erst einmal ist es als C++ entwickler immer gut einen Link zu einer C++ Referenz zu haben.
Also für die STL z.B. :)

Hier mal ein alter den ich gerne nutze:
http://www.cppreference.com/wiki

1.Ich würde sagen, dass liegt an einer Typenunverträglichkeit :p
Muss ich aber gerade raten ^^

2.Naja kommt drauf an was du gerade meinst :/
Dein Code hat hier und da noch ein paar unschöne Flecken.

Code: Alles auswählen

if (argc != 3) {
      cerr << "Usage: " << argv[0] << " <InputFile> <OutputFile>" << endl;
        exit(1);
   }
Hier ist deine Bedingung recht schwammig.
Was passiert wenn keine Argumente an dein Programm übergeben wurden, du aber trotzdem auf das 0 Argument zugreifst.
Hier müsste es knallen und dein Debugger wird dir was sagen von Index out of Range :p

Das dazugehörige else ist auch ein Unding.
Prüf lieber auf argc == 3.
Somit weißt du, dass 3 Argumente entgegen genommen wurden.
Alles andere ist hier eher unsicher.

Das else ist dann dein != 3 Fall.
Somit ist die Sache schon klarer und sicherer :)

Des weiteren fehlt eine effektive Nutzung von Exceptions.
Du arbeitest immer noch wie ein C Programmierer mit true/false Rückgabe werden.
Auch return 1 in Main ist doch etwas unpassend.
Ein Anwender sollte informiert werden, wenn etwas nicht stimmt.
ein Ausgabewert von 1 sagt keinem Menschen was :)

Wirf bei folgendes lieber eine Exception die per what gibst du dann den Grund an.

Code: Alles auswählen

if( !fileExist(input_file))
         return 1;
Einfach eine Exception mit Begründung "Datei " + input_file + " wurde nicht gefunden".
Somit ist dem Anwender bei der Ausgabe von dem what bei der Exception schon klarer was nicht stimmt.

Code: Alles auswählen

exit(1);
Sowas ist nicht gerade schön.
Auch wenn das Betriebssystem z.b. reservierten Speicher wieder freigibt, muss dies nicht für geöffnete Dateien oder manchmal auch Datenbankverbindungen stimmen ;)
Besser auf exit verzichten, vor allem bei komplexen Programmen hier ist es aber noch okay.

in deinem try Block öffnest du zwar die Datei, aber geschlossen wird diese nicht.
Hier müsstest du spätestens im catch Block die Datei per close() schliessen.

Einige kleine Tipps :p

Martin
Es gibt keine if Schleife -> http://www.if-schleife.de/
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever :D

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 21.04.2009 19:50:59

Duff hat geschrieben:Aber wieso kann ich an ofstream f2 nicht den Stringnamen output_file übergeben?
Weil ifstream/ofstream aus total undurchschaubaren (vermutlich inexistenten) Gründen keinen Konstruktor haben der einen C++ String als Argument akzeptiert. Du must denen einen C-String (d.h. ein nullterminiertes Char-Array) als Argument übergeben; das kriegst du mit der Methode c_str() von einem String-Objekt...
Duff hat geschrieben:Danke, aber ich befürchte, dass du mich jetzt ein wenig abgehängt hast.
Ok, hier mal ein Codebeispiel das die von mir vorgeschlagene Trennung von Dateihandling und dem eigentlichen Algorithmus implementiert; Exceptions und ähnliches habe ich nicht mit eingebaut, das macht den Code nur erst mal unleserlich:

Code: Alles auswählen

#include <iostream>
#include <fstream>
using namespace std;

// Methode die die eigentliche Verschlüsselung macht; arbeitet mit beliebigen input/output streams
void encrypt(istream& istream, ostream& ostream, const string& key) {
  int i = 0;
  int keysize = key.size();
  char ch;
  while(istream.get(ch)) {
    ostream.put(ch ^ key[i]);
    i++;
    if(i >= keysize)
      i = 0;
  }
}

// Methode die die Dateien öffnet und damit verbundenes Errorhandling macht
void encrypt(const string& input_file, const string& output_file, const string& key) {
  // hier noch testen ob die Dateien überhaupt existieren und entsprechende Exceptions werfen
  ifstream in(input_file.c_str());
  ofstream out(output_file.c_str());
  encrypt(in, out, key);
}
 
// Methode die den Schlüssel einliest
const string read_key() {
  cout << "Enter key: " << endl;
  string s;
  getline(cin, s);
  return s;
}

int main(int argc, char** argv) {
  if (argc != 3) {
    cerr << "Usage: " << argv[0] << " <InputFile> <OutputFile>" << endl;
    return 1;
  }
  else {
    encrypt(argv[1], argv[2], read_key());
    // hier eventuell Exceptions abfangen und Fehlermeldung(en) ausgeben
  }

  return 0;
}
Das gute an der Aufteilung ist, dass der eigentliche Algorithmus wiederverwendbar ist. Stell dir vor du hast ein paar Strings - die kannst du mittels der Klasse std::stringstream auch in streams verwandeln und genauso als istream/ostream verwenden:

Code: Alles auswählen

#include <iostream>
#include <sstream>
using namespace std;

// Methode die die eigentliche Verschlüsselung macht; arbeitet mit beliebigen input/output streams
void encrypt(istream& istream, ostream& ostream, const string& key) {
  //...
}

int main(int argc, char** argv) {
  stringstream in("Bla bla bla bllllllll");
  std::cout << "Originaltext: " << in.str() << std::endl;
  stringstream crypted, decrypted;
  string key("asdf");

  encrypt(in, crypted, key);
  std::cout << "Verschlüsselt: " << crypted.str() << std::endl;
  
  encrypt(crypted, decrypted, key);
  std::cout << "Entschlüsselt: " << decrypted.str() << std::endl;  

  return 0;
}
MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 21.04.2009 20:10:25

Milbret hat geschrieben:

Code: Alles auswählen

if (argc != 3) {
      cerr << "Usage: " << argv[0] << " <InputFile> <OutputFile>" << endl;
        exit(1);
   }
Hier ist deine Bedingung recht schwammig.
Was passiert wenn keine Argumente an dein Programm übergeben wurden, du aber trotzdem auf das 0 Argument zugreifst.
Hier müsste es knallen und dein Debugger wird dir was sagen von Index out of Range :p
Das 0. Argument ist der Programmname und immer da...
Auch return 1 in Main ist doch etwas unpassend.
Ein Anwender sollte informiert werden, wenn etwas nicht stimmt.
ein Ausgabewert von 1 sagt keinem Menschen was :)
return 1 ist sehr passend; erst diese kleinen Sachen machen Bash-Scripts überhaupt möglich... - eine kleine textliche Fehlermeldung zusätzlich würde an der Stelle allerdings tatsächlich nicht schaden.

Code: Alles auswählen

exit(1);
Sowas ist nicht gerade schön.
Auch wenn das Betriebssystem z.b. reservierten Speicher wieder freigibt, muss dies nicht für geöffnete Dateien oder manchmal auch Datenbankverbindungen stimmen ;)
Besser auf exit verzichten, vor allem bei komplexen Programmen hier ist es aber noch okay.
Ja, exit ist ein bisschen kritisch, weil damit (im Gegensatz zu "return 1;") die Destruktoren der Objekte auf dem Stack nicht aufgerufen werden. Zumindest auf Linux nicht - auf Windows ist das laut Doku anders.

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 22.04.2009 13:23:18

Erstmal Danke für die lange und gute Erklärung.

Das Programm encrypt verstehe ich soweit und kann ich nachvollziehen. Allerdings erinnert es mich eher an ein Programm, welches ich in sonst in Bash oder perl geschrieben hätte und nicht wirklich an OOP.
Mir fehlen da irgendwie die Klassen. Oder sehe ich das falsch?

Den Punkt mit der Wiederverwendbarkeit finde ich super. Genau so was möchte ich anwenden können. Nur leider weiß ich noch nicht genau wie.
HAbe es mal versucht mit dem 2ten Code zu kompilieren, dies funktioniert aber nicht, da die Typumwandlung nicht so will.
Müsste ich hier eventuell STL anwenden?

Code: Alles auswählen

daniel@daniel-laptop:~/scripts/C++/Projekte/xor$ g++ -Wall -o stringstream stringstream.cpp encrypt.cpp 
stringstream.cpp: In function ‘int main(int, char**)’:
stringstream.cpp:19: error: invalid conversion from ‘void*’ to ‘char*’
stringstream.cpp:19: error: invalid conversion from ‘void*’ to ‘int’
/usr/include/unistd.h:1078: error: too many arguments to function ‘void encrypt(char*, int)’
stringstream.cpp:19: error: at this point in file
stringstream.cpp:22: error: invalid conversion from ‘void*’ to ‘char*’
stringstream.cpp:22: error: invalid conversion from ‘void*’ to ‘int’
/usr/include/unistd.h:1078: error: too many arguments to function ‘void encrypt(char*, int)’
stringstream.cpp:22: error: at this point in file
Sorry für die vielen Fragen, aber ich bin noch Anfänger in Sachen C++.


Danke & Gruß,
Daniel
Oh, yeah!

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 22.04.2009 20:02:12

Duff hat geschrieben:Erstmal Danke für die lange und gute Erklärung.
Bitteschön.
Das Programm encrypt verstehe ich soweit und kann ich nachvollziehen. Allerdings erinnert es mich eher an ein Programm, welches ich in sonst in Bash oder perl geschrieben hätte und nicht wirklich an OOP.
Mir fehlen da irgendwie die Klassen. Oder sehe ich das falsch?
Jein. Du hast eine sehr schöne Verwendung von OOP in der encrypt(istream, ostream, string)-Methode. Da kannst (und tust) du jede möglichen Objekte von istream/ostream abgeleiteten Stream-Klassen übergeben und (dank virtual-Funktionen) funktioniert auch alles prächtigstens.

Dass dein Algorithmus nicht in einer Klasse steckt braucht dich erst mal nicht zu kümmern; für so etwas bringt OOP auch gar nix. Nützlich würde sowas erst wenn du z.B. einen Haufen verschiedener Kryptoalgorithmen hättest die du dann in Klassen steckst die von einer gemeinsamen Basisklasse abgeleitet sind. Genau gleich für Hashalgorithmen mit denen du das Passwort verwurstelst. Oder so.

OOP brauchst du und bringt dir erst was wenn das Programm als ganzes komplexer wird, du viele Bausteine hast die eigentlich unabhängig voneinander sind/sein können und/oder so.

Genausogut könntest du dich darüber beklagen dass da kein Template Metaprogramming vorkommt. Aber darüber bist du dann andererseits wohl froh :P
Den Punkt mit der Wiederverwendbarkeit finde ich super. Genau so was möchte ich anwenden können. Nur leider weiß ich noch nicht genau wie.
HAbe es mal versucht mit dem 2ten Code zu kompilieren, dies funktioniert aber nicht, da die Typumwandlung nicht so will.
Ich bin mir nicht ganz sicher was du in den beiden Dateien stehen hast die du hier aufs Mal zu kompilieren versuchst. Mein zweites Codebeispiel war so gedacht dass du dort wo "//..." stehst einfach den Funktionsinhalt der entsprechenden Funktion aus dem ersten Codebeispiel reinkopierst. Wenn du das machst geht der Code auch problemlos (solange du mit g++ nur diese eine Datei aufs Mal kompilierst)

Natürlich kannst du z.B. auch die Funktion in eine eigene cpp-Datei auslagern, ein passendes Header erstellen und dann so kompilieren wie dus hier gepostet hast. Ohne dass du die Dateien postest wie du sie rumliegen hast kann ich dir aber schlecht weiterhelfen...

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 23.04.2009 10:21:25

peschmae hat geschrieben: Natürlich kannst du z.B. auch die Funktion in eine eigene cpp-Datei auslagern, ein passendes Header erstellen und dann so kompilieren wie dus hier gepostet hast.
So würde ich es gerne machen. Dann könnte ich immer auf diese Funktion zurückgreifen. Auch in anderen Programmen.

Muss ich die Funktion denn dann nicht in eine Klasse unterbringen?
Oder würde sowas auch mit namespace funktionieren?

Wäre für eine kleine Hilfe bei der Umsetzung dankbar. Muss nicht der gesamte Code sein, sondern eher ein paar Informationen zur Vorgehensweise. Man(n) will ja was lernen ;-)
Oh, yeah!

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 23.04.2009 16:48:32

Duff hat geschrieben:
peschmae hat geschrieben: Natürlich kannst du z.B. auch die Funktion in eine eigene cpp-Datei auslagern, ein passendes Header erstellen und dann so kompilieren wie dus hier gepostet hast.
So würde ich es gerne machen. Dann könnte ich immer auf diese Funktion zurückgreifen. Auch in anderen Programmen.

Muss ich die Funktion denn dann nicht in eine Klasse unterbringen?
Oder würde sowas auch mit namespace funktionieren?
Dazu brauchst eigentlich noch nicht mal einen Namespace.

Es reicht wenn du die Funktionsdeklaration in ein Header schreibst - encrypt.h:

Code: Alles auswählen

void encrypt(istream& istream, ostream& ostream, const string& key);
(Natürlich noch das übliche #ifdef-Geramse drumherum und die nötigen Includes mit rein damit er istream/ostream und string kennt - also die fstream und string headers).

Dazu den Code nach encrypt.cpp

Code: Alles auswählen

#include "encrypt.h"
void encrypt(istream& istream, ostream& ostream, const string& key) {
 // ...
}
und den rest nach main.cpp:

Code: Alles auswählen

#include "encrypt.h"
#include <sstream>
int main(int argc, char** argv) {
  // ...
}
Dann:

Code: Alles auswählen

g++ stringstream.cpp encrypt.cpp -o stringstream
Einen Namespace für die encrypt funktion einzuführen wäre auch nicht soo schlecht - aber das ist ein nächster Schritt.. ;)

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 23.04.2009 17:02:19

DAnke. Ich muss aber leider nochmals nachfragen.

Meinst du es so: http://nopaste.debianforum.de/21020?

DAs Programm funktioniert auf jeden Fall damit...
http://nopaste.debianforum.de/21022


Wenn dies so korrekt ist, werde ich mal versuchen die Exceptions abzufangen.
Muss ich dafür eine eigene Exceptionsklasse erstellen?
Oh, yeah!

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 23.04.2009 19:41:31

Ja, das sieht gut aus so.
Duff hat geschrieben:Muss ich dafür eine eigene Exceptionsklasse erstellen?
Das kommt darauf an. Die ifstream/ofstreams werfen ja erst mal eigene Exceptions, wenn du die angeschaltet hast. Eine eigene Exception-Klasse (also von std::exception ableiten und das "string what()" überschreiben) würde ich wohl für den Fall machen dass die Datei nicht existiert.

Dann kannst du z.B. in main() sämtliche Exceptions auf einen Schlag abfangen und einfach deren "what()" als Fehlermeldung ausgeben, genau wie Trigger das vorgeschlagen hat.

Je nach dem wie du dein Fehlerhandling genau ausgestalten willst musst du auch mehrere Exception-Klassen erstellen - z.B. eine pro Fehlerart, damit du die nachher einfach auseinanderhalten und verschieden behandeln kannst.

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 23.04.2009 19:42:53

Zusätzliches - was mit deiner eigentlichen Frage eigentlich nichts zu tun hat: ;)

[OT]
In der Praxis bin ich im übrigen kein grosser Fan von Exceptions; ich sehe das mehr als notwendiges Übel. Das Problem ist vor allem folgendes: Stell dir vor du benutzt irgend eine Bibliothek (die du nicht selbst geschrieben hast) und eine Methode wirft eine Exception die du nirgendwo auffängst. Was ganz normal ist - in der Praxis hast du kaum eine Möglichkeit zu überprüfen was alles für Exceptions eine Methode werfen kann, geschweige noch wirst du die alle abfangen. Wenn du das tun würdest wäre dein Programm potthässlich und unleserlich wegen der vielen try-except Klauseln...

Ergo crasht das Programm einfach so ohne dass du auch nur die mindeste nützliche Information dazu hast was jetzt los war.

Ok, dann schreibst du halt eine grosse try-catch Klausel in main() um allen Code herum - aber auch dort fängst du nur Exceptions ab die von std::exception abgeleitet wurden; und für die weisst du auch nicht mehr als was in .what() steht - du hast keinen Plan wo die Exception geworfen wurde...

In Java geht das viel besser - da kriegst du einen automatischen Stacktrace...

In C++ kann man sowas auch machen - ein Bekannter von mir hat das mal implementiert - d.h. Code der dem Stack entlanggeht und zumindest die Funktionsnamen ausgibt die aufm Stack rumliegen (und die natürlich vorher entsprechend demangled) - eine ziemliche Übung; die Codezeilen kriegst du allerdings von einem C++ Programm nicht so einfach heraus... ;)

Natürlich ist das alles kein Problem solange du alle Exceptions selber wirfst und/oder genau weisst wer welche werfen kann (und das nicht zu viele sind).
[/OT]

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 23.04.2009 20:14:07

Ok, danke. Dann muss ich erstmal überlegen, ob ich überhaupt die ganzen möglichen Exception behandeln möchte.

Mir ist beim Kompilieren im letzten Posts nicht ganz klar, warum ich in der main-Datei nochmals die Header-Datei encrypt.h einbinden muss. In der encrypt.h stehen ja nur die Deklarationen und in der encrypt.cpp die Definitionen. Kann ich nicht aus den beiden DAteien schon eine Objekt-Datei erstellen, die dann anschließend zum Kompilieren der main-Datei genutzt werden kann?

Hintergrund: Wenn ich nun jemanden nicht alle meine Dateien im Quellcode geben möchte, sondern nur die "Schnittstellen". Wie muss ich dass dann auf dieses Beispiel bezogen machen?
Oh, yeah!

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 24.04.2009 10:22:33

Duff hat geschrieben:Ok, danke. Dann muss ich erstmal überlegen, ob ich überhaupt die ganzen möglichen Exception behandeln möchte.
Ich denke gerade für das Beispiels sind Exceptions gar nicht soo schlecht geeignet.

Wollte nur angemerkt haben dass das auch nicht der heilige Gral der Fehlerbehandlung ist (In Java ist es das schon; weil du da immer schöne nutzbare Backtraces kriegst...) ;)
Mir ist beim Kompilieren im letzten Posts nicht ganz klar, warum ich in der main-Datei nochmals die Header-Datei encrypt.h einbinden muss. In der encrypt.h stehen ja nur die Deklarationen und in der encrypt.cpp die Definitionen. Kann ich nicht aus den beiden DAteien schon eine Objekt-Datei erstellen, die dann anschließend zum Kompilieren der main-Datei genutzt werden kann?
Ja, die beiden Dateien reichen um eine Objekt-Datei zu erstellen. Also mit g++ -o encrypt.o -c encrypt.cpp. Includen musst du das Header - also die Funktionsdeklaration in main trotzem - sonst weiss der Compiler wenn er die main-Datei kompiliert ja gar nicht dass es eine Funktion encrypt(istream&, ostream&, string) gibt...

(Ohne das Header würde der Compiler mit -Wall eine Warnung ausspucken und einfach annehmen dass die Funktion existiert und einen int als Rückgabewert hat. Oder so ähnlich - das ist ein absolut dummes Verhalten, stammt halt noch aus den seeligen C-Zeiten... ;))
Hintergrund: Wenn ich nun jemanden nicht alle meine Dateien im Quellcode geben möchte, sondern nur die "Schnittstellen". Wie muss ich dass dann auf dieses Beispiel bezogen machen?
Dazu würdest du dann das Header - also encrypt.h und die Objektdatei encrypt.o weitergeben. Oder natürlich in der Praxis eher eine Shared Library - encrypt.so plus das Header encrypt.h.

Ich würde mir allerdings noch nicht all zu viele Sorgen um solche Sachen machen. Solange ein Programm klein ist lässt du bequemerweise alles in einer Datei. Das ist einfacher zu kompillieren (ein einfacher g++-Befehl reicht), zu bearbeiten (du musst nicht immer deklaration/definition separat und in zwei verschiedene Dateien schreiben) und zu durchsuchen (du musst nicht durch hunderte von Dateien waten um eine bestimmte Funktion zu finden sondern nimmst einfach die Suchfunktion des Texteditors).

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 08.05.2009 10:39:08

peschmae hat geschrieben: Ja, die beiden Dateien reichen um eine Objekt-Datei zu erstellen. Also mit g++ -o encrypt.o -c encrypt.cpp. Includen musst du das Header - also die Funktionsdeklaration in main trotzem - sonst weiss der Compiler wenn er die main-Datei kompiliert ja gar nicht dass es eine Funktion encrypt(istream&, ostream&, string) gibt...
Danke, genau das hatte ich gesucht!

peschmae hat geschrieben: Hintergrund: Wenn ich nun jemanden nicht alle meine Dateien im Quellcode geben möchte, sondern nur die "Schnittstellen". Wie muss ich dass dann auf dieses Beispiel bezogen machen?

Dazu würdest du dann das Header - also encrypt.h und die Objektdatei encrypt.o weitergeben. Oder natürlich in der Praxis eher eine Shared Library - encrypt.so plus das Header encrypt.h.
Wie dass mit der Shared Libary genauc funktioniert, weiß ich noch nicht genau. Müsste ich mir dann ggf. mal anschauen, wobei ich als "Hobby-"Programmierer wohl eh nur bei kleinen Programmen bleiben werde.
Oh, yeah!

Milbret
Beiträge: 827
Registriert: 26.05.2008 12:04:54
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Nörten-Hardenberg
Kontaktdaten:

Re: C++ und Exception-Handling einbauen...

Beitrag von Milbret » 16.05.2009 10:51:47

Hallo,
das System mit den shared Objects ist eigentlich das gleiche wie bei Windows mit den .dlls :)
Du gibts nur die header Dateien, die .a und die .so Datei weiter.

Was Header Dateien sind, ist klar.
Bei den .a Dateien handelt sich es um die Datei, die der Linker benötigt um dein Programm gegen deine .so Datei zu linken.
Die .so Datei ist dann eine ".dll"

Ist an sich simpel erklärt.
Aber die Programmierung von .dll und .so Dateien hat mir nicht wirklich zu gesagt.
Im Moment mache ich auch mehr mit Java im kleinen Kreis.
Dort schnüre ich mir meine .jar "libs" und hab alles was ich brauche ;)

Martin
Es gibt keine if Schleife -> http://www.if-schleife.de/
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever :D

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++ und Exception-Handling einbauen...

Beitrag von peschmae » 16.05.2009 18:30:07

Duff hat geschrieben: Wie dass mit der Shared Libary genauc funktioniert, weiß ich noch nicht genau. Müsste ich mir dann ggf. mal anschauen, wobei ich als "Hobby-"Programmierer wohl eh nur bei kleinen Programmen bleiben werde.
Im Prinzip reicht es einfach alles was in die Shared Library gehört mittels

Code: Alles auswählen

g++ -shared -o libshared.so blabla.cpp
zu kompilieren und linken und anschliessend mittels

Code: Alles auswählen

g++ -L/ordner/wo/die/libshared.so -lshared -o programmname baksdjf.cpp
das Programm zu erstellen und gegen die libshared.so zu linken.
Mlibret hat geschrieben: Bei den .a Dateien handelt sich es um die Datei, die der Linker benötigt um dein Programm gegen deine .so Datei zu linken.
Die .so Datei ist dann eine ".dll"
Nein, die .a - Dateien sind statische Libraries; genauer gesagt ist das ein Haufen .o-Dateien die mit dem Programm ar in ein Archiv gepackt wurden.

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: C++ und Exception-Handling einbauen...

Beitrag von Duff » 16.05.2009 21:35:31

Danke für die Erläuterung und die Beispiele.


Vielleicht werde ich es ja mal anwenden, wenn ich wüßte wann und zu welchem Zweck.
Oh, yeah!

Milbret
Beiträge: 827
Registriert: 26.05.2008 12:04:54
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Nörten-Hardenberg
Kontaktdaten:

Re: C++ und Exception-Handling einbauen...

Beitrag von Milbret » 17.05.2009 10:20:12

Guten Morgen,
Nein, die .a - Dateien sind statische Libraries; genauer gesagt ist das ein Haufen .o-Dateien die mit dem Programm ar in ein Archiv gepackt wurden.
arg stimmt :)
Ist schon eine sehr lange Weile her als ich das letzte mal mit C/C++ gearbeitet habe.
Muss wohl mal wieder ein kleines Projekt machen, damit ich mal wieder fitter werde ^^

Martin
Es gibt keine if Schleife -> http://www.if-schleife.de/
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever :D

Antworten