Samstag, 16. März 2013

Datei Input / Output in C++: Teil II - Datei-Input

Um Informationen aus Dateien lesen zu können, wird wieder der Header fstream benötigt. In diesem wird die Klasse ifstream definiert. Von dieser kann man eine Variable mit beliebigem Namen erstellen. Meist wird die Variable jedoch fin (für file-input) genannt, um die Nähe zu cin (console-input) kenntlich zu machen.
#include <fstream>
ifstream fin;
Nun muss man seine Variable noch mit einer Datei verknüpfen, dies kann durch die Funktion open() realisiert werden.
fin.open("file.txt");
Da es jedoch zu Fehlern kommen kann, wenn man eine Datei öffnet, die nicht existiert, sollte man nach dem Öffnen der Datei prüfen, ob die Datei auch wirklich geöffnet wurde. Für diesen Zweck wird die Funktion is_open() bereitgestellt.
fin.open("file.txt");
if (!fin.is_open())
{
    exit(EXIT_FAILURE);
}
Die Funktion exit() ist sehr nützlich um ein Programm schnell zu beenden, sie wird in der Header-Datei cstdlib bereitgestellt.
Es gibt verschiedene Wege um Informationen aus einer Datei zu lesen, den >> Operator, die Funktion get(), sowie die Funktion getline(). Möchte man z.B. einer Integer Variablen einen Wert aus der Datei zuweisen, so kann man dies mit >> realisieren.
int i=0;
fin >> i;
Dies geht natürlich nur, wenn in der Datei auch an erster Stelle ein Integer-Wert steht. Handelt es sich bei der Datei um eine Textdatei, so kann man mit get() einzelne Zeichen und mit getline() ganze Zeilen lesen.
char ch;
char line[50];
fin.get(ch);
fin.getline(line, 50);
Die Funktion getline() benötigt als Argument ein Array von char Werten. Es liest die Zeile soweit, bis sie entweder endet, oder bis das Array voll ist, d.h. in diesem Beispiel die ersten 50 Zeichen.
Wenn man alle Informationen aus der Datei gelesen hat, sollte man diese mit der Funktion close() abschließen.
fin.close();
Hier könnt ihr euch einen Beispielcode ansehen oder herunterladen.

Dienstag, 12. März 2013

Datei Input / Output in C++: Teil I - Datei-Output

Die meisten Programme arbeiten mit Dateien. Texteditoren, um Text zu Speichern bzw. zu Lesen oder Spiele um z.B. Speicherstände zu Laden bzw. zu Schreiben. Wie die grundlegende Datei Ein- und Ausgabe funktioniert, soll in dieser zweiteiligen Reihe erklärt werden. Da das Schreiben in eine Datei etwas einfacher ist, als aus einer Datei zu Lesen, werde ich mit Datei-Output beginnen.

In eine Datei zu schreiben ist nicht viel schwieriger, als Text auf die Konsole auszugeben ( cout ). Man muss jedoch anstatt die Header-Datei iostream (input-output-stream) den Header fstream (file-stream) einbinden.
#include <fstream>
Nun kann man sich eine Variable des Typs ofstream erstellen, diese kann man benennen wie man möchte, es bietet sich jedoch fout (für file-out) an, um die Ähnlichkeit zu cout (console-out) erkenntlich zu machen.
ofstream fout;
Diese Variable kann nun mit einer Datei verknüpft werden. Die Klasse ofstream stellt dazu die Funktion open() bereit. Diese erhält als Argument den Pfad zu der Datei, mit welcher man arbeiten möchte. Ist diese Datei nicht vorhanden, so wird automatisch eine leere Datei mit dem übergebenen Namen erstellt. Gibt man keinen speziellen Pfad an, so sucht das Programm im Verzeichnis, in welchem es ausgeführt wird nach der Datei bzw. erstellt sie dort.
fout.open("foo_bar.txt");
Nun kann man fout genau wie cout verwenden, der Unterschied ist jedoch, dass die Ausgabe nicht auf die Konsole geleitet wird sondern in die Datei.
fout << "Ausgabe des Programms" << endl;
Einen Beispielcode könnt ihr euch hier ansehen, oder herunterladen.

Montag, 25. Februar 2013

Beliebig viele nummerierte Ordner mit einem Befehl erstellen (Linux)

Diese Situation kennt bestimmt jeder, man braucht mehrere nummerierte Ordner und hat keine Lust jeden einzeln zu erstellen. Für diejenigen die nicht wissen, was gemeint ist, hier ein kleines Beispiel:
Man ist Programmierer und möchte seine fertigen Projekte nach Jahren sortiert auf einer externen Festplatte archivieren. Natürlich kann man jeden Ordner einzeln erstellen, doch es gibt eine viel komfortablere Möglichkeit. Man wechselt mit dem Terminal in das Verzeichnis, in welchem man die Ordner erstellen möchte:

cd gewünschtes/Verzeichnis

Der Befehl zum Erstellen der Ordner sieht folgendermaßen aus:

for i in {x1..x2}; do mkdir "Ordnername ${i}"; done

Was auf den ersten Blick vielleicht etwas kompliziert aussieht, ist eigentlich überhaupt nicht schwer. Die Ordner werden mit Hilfe einer for-Schleife durchnummeriert, dabei geht die Variable i alle der for-Schleife übergebenen Argumente durch. x1 und x2 stellen den Anfangswert und den Endwert dar. Möchte man z.B. 50 Ordner erstellen kann man für x1 eine 1 und für x2 eine 50 schreiben, natürlich geht auch jeder andere Zahlenbereich (z.B. 250..299, etc). Der Befehl mkdir erstellt die Ordner mit dem übergebenen Namen, mit ${i} erhält man den Wert der Variablen i, da dieser nach jedem Schleifendurchlauf verschieden ist, wird bei jedem Durchlauf ein neuer Ordner erstellt. 
Um wie im obigen Beispiel z.B. ein nach Jahren sortiertes Archiv (z.B. von 2009 bis 2013) für seine Projekte anzulegen, sieht der Befehl folgendermaßen aus.

for i in {2009..2013}; do mkdir "Projekte ${i}"; done

Die nun im Verzeichnis liegenden Ordner sind demnach:

Projekte 2009    Projekte 2010    Projekte 2011
Projekte 2012    Projekte 2013

Mittwoch, 13. Februar 2013

Binäroperatoren

Wie man hier sehen kann, gibt es in fast allen Programmiersprachen die sogenannten binären oder bitweisen Operatoren.
Diese sind:
   & - bitweises AND (Und-Verknüpfung)
   | - bitweises OR  (Oder-Verknüpfung)
   ^ - bitweises XOR (exklusives Oder)
   ~ - bitweises NOT (Negation)
Wie diese im einzelnen funktionieren, soll nun anhand von Beispielen verdeutlicht werden.

Die UND-Verknüpfung

Bei der Und-Verknüpfung wird jede Binärstelle des linken Operanden mit der selben Stelle des rechten Operanden verglichen. Dabei ist diese Stelle im Ergebnis genau dann 1, wenn beide Operanden an dieser Stelle ebenfalls eine 1 stehen haben, anderenfalls ist diese Stelle im Ergebnis 0.

Beispiel:
  3 & 1       | in Binär umwandeln
  0011 & 0001 | Da nur an Stelle 0 bei beiden eine 1 steht, ist das Ergebnis 0001
  0001        | in Dezimal also 1
  1           | fertig!

Die ODER-Verknüpfung

Hier werden ebenfalls die gleichen Stellen beider Operanden verglichen. Jedoch ist hier das Ergebnisbit 1, wenn mindestens dieses Stelle bei einem Operanden 1 ist. Sind beide Stellen 0, so ist auch die Stelle im Ergebnis 0.

Beispiel:
  3 | 1       | in Binär umwandeln
  0011 | 0001 | Stelle 0 ist bei beiden 1 und Stelle 1 ist beim ersten Operanden 1
  0011        | in Dezimal also 3
  3           | fertig!

Die XOR-Verknüpfung

Beim exklusiven Oder ist das Ergebnisbit nur 1, wenn eine der beiden Stellen der Operanden 1 ist. Sind beide Stellen 0 oder 1, so ist das Ergebnisbit 0. Dies kann man sich sehr gut durch ein Beispiel aus dem realen Leben vorstellen.
Der Satz: "Hände hoch, oder ich schieße" ist eine typisches exklusives Oder, denn er stellt nur dann eine wahre Aussage (in binär 1) dar, wenn genau eine der beiden Aussagen zutrifft. Sind die Hände oben und man schießt trotzdem oder werden die Hände unten gelassen und man schießt nicht, so ist die ursprüngliche Aussage falsch (in binär 0).

Also:
  3 ^ 1       | in Binär umwandeln
  0011 ^ 0001 | Da an Stelle 1 nur eine 1 steht, ist das Ergebnis 0010
  0010        | in Dezimal also 2
  2           | fertig!

Die Negation

Das bitweise Nicht negiert lediglich jedes Bit. Das heißt, aus 0 wird 1 und aus 1 wird 0.

Beispiel:
  ~3    | in Binär umwandeln
  ~0011 | negieren
   1100 | VORSICHT! Das Ergebnis ist nicht 12, sondern -4
  -4    | Warum das so ist, könnt ihr hier nachlesen

Freitag, 8. Februar 2013

Darstellung negativer Zahlen: Zweierkomplement und VZB-Darstellung

Wie ein Rechner positive Zahlen darstellt kann man hier nachlesen. Ein Computer kann aber nicht nur mit positiven, sondern auch mit negativen Zahlen rechnen. Wie der Rechner diese darstellt, soll hier kurz verdeutlicht werden.

Es gibt verschiedene Möglichkeiten negative Zahlen binär darzustellen, die beiden bekanntesten sind die Vorzeichen-Betrags-Darstellung und das Zweierkomplement. Das am häufigsten verwendete Verfahren ist jedoch die Darstellung als Zweierkomplement. Dennoch werde ich hier beide Verfahren vorstellen.

Anmerkung: 
Ich werde die Binärzahlen in diesen Beispielen zur Veranschaulichung mit lediglich 4 Stellen angeben. Natürlich schaut dies in der Praxis anders aus. Das Prinzip bleibt aber das selbe.

VZB-Darstellung
Möchte man beispielsweise die Zahl -7 in VZB-Darstellung repräsentieren, so muss man zunächst ihren Betrag, also +7, im Binärsystem darstellen, also 0111. Die VZB-Regel besagt, dass das erste Bit bei positiven Zahlen 0 und bei negativen Zahlen 1 sein soll. Da -7 offensichtlich negativ ist muss hier das erste Bit auf 1 gesetzt werden, also ist -7 in VZB-Darstellung 1111.

Schritt für Schritt:
1) -7     | Betrag berechnen
2)  7     | Binär darstellen
3) 0111   | erstes Bit auf 1 setzen
4) 1111   | fertig!

Zweierkomplement-Darstellung
Auch hier sei als Beispiel wieder die Zahl -7 gewählt. Möchte man diese als Zweierkomplement darstellen, so muss man zunächst ebenfalls den Betrag im Binärsystem hinschreiben. Nun muss man jedoch alle Bits invertieren, das bedeutet, aus 1 wird 0 und aus 0 wird 1. Bei -7 würde aus 0111 demnach 1000 werden. Danach ist man jedoch noch nicht fertig, zum Schluss wird nämlich noch binär eine 1 addiert. -7 in Zweierkomplement-Darstellung ist also 1001.

Schritt für Schritt:
1) -7     | Betrag berechnen
2)  7     | Binär darstellen
3) 0111   | invertieren
4) 1000   | 1 addieren
5) 1001   | fertig!

Donnerstag, 31. Januar 2013

CHM-Dateien unter Linux mit Wine öffnen

Unter Linux gibt es verschiedene Möglichkeiten CHM-Dateien auch ohne Wine zu öffnen, wie z.B. chmsee. Wenn man jedoch ohnehin Wine nutzt, ist es eigentlich unnötig sich zusätzliche Software zu installieren, da Wine ohne Probleme mit diesen Dateien umgehen kann. Leider kann man die Datei nicht per Rechtsklick->"Mit hh öffnen" (hh ist das Programm zum Öffnen von chm-Dateien unter Windows) öffnen, wie der folgende Screenshot zeigt.


Dies heißt jedoch nicht, dass Wine keine chm's öffnen kann. Man muss lediglich diesen Code ins Terminal eingeben und schon wird die chm problemlos geöffnet:

wine hh.exe `winepath -w /Verzeichnis/Datei.chm`

Das Kommando winepath -w konvertiert den Linux-Verzeichnispfad in einen Windowspfad. Dadurch kann die chm-Datei von dem Programm hh erkannt und ausgeführt werden.

Samstag, 26. Januar 2013

Frogger - An unexpected Journey

Heute stelle ich euch mein erstes "größeres" Projekt vor. Im Rahmen meines Studiums musste ich eine Variante des altbekannten Spiels "Frogger" in Java zusammen mit der Game-Library Slick2D programmieren. Diese ist nun fertig und ich möchte sie euch natürlich nicht vorenthalten. Das Spiel hat einen Singleplayer- und sogar einen Multiplayer-Modus mit jeweils vier verschiedenen Leveln.
Unten findet ihr die Downloads für Windows, Linux, Mac und Solaris, sowie den Java Sourcecode. Solltet ihr Probleme oder Fragen zum Spiel haben, könnt ihr mir gerne eine E-Mail schreiben oder die Frage in den Kommentaren stellen. Ich werde sie selbstverständlich so schnell wie möglich versuchen zu beantworten.
Hier ein Screenshot des ersten Levels:


Ich hoffe das Spiel gefällt euch und bin für euer Feedback sehr dankbar. Viel Spass beim Zocken!

Downloads: