Hallo zusammen
In der Schule machen wir ien Schulprojekt in Informatik.
Und zwar mache ich ein Verschlüsselungsprogramm. Es verschlüsselt einen
Text von einer txt-Datei in eine Bild-Datei (tif-Datei).
Wir haben es so gelöst, dass es jedes ASCII-Zeichen von der txt-Datei
bitweise verschlüsselt. und zwar wird immer das LSB von einem Byte in
der Bilddatei entweder gelöscht oder gesetzt, je nachdem ob das Bit vom
ASCII-Zeichen gesetzt ist oder nicht.
-> Um ein ASCII-Zeichen zu verschlhüsseln, braucht man 8 Byte von der
Bild-Datei
Nun meine Frage. Ich muss ein Byte von der Bild-Datei holen und später
wieder verändert abspeichern.
Mit fgetc lese ich das Byte aus und mit fputc speichere ich es ab.
Da aber ein Zeiger eine Stelle rechts schiebt, wenn er gebraucht wird,
habe ich einen 2ten gemahct, aber dieser schiebt sich auch nach rechts,
wenn ich den 1en benutze. Kann man das nicht ändern?
Und wie geht der Modus, bei dem ich Lesen/Schreiben kann und er soll ein
neues File erstellen, wenn File nicht vorhanden ist.
vielen Dank
Robert schrieb:> Mit fgetc lese ich das Byte aus und mit fputc speichere ich es ab.> Da aber ein Zeiger eine Stelle rechts schiebt, wenn er gebraucht wird,> habe ich einen 2ten gemahct, aber dieser schiebt sich auch nach rechts,> wenn ich den 1en benutze. Kann man das nicht ändern?
Mit den Stream-Funktionen geht das m.W. nicht, was du vorhast.
Da wirst du jeweils zwischen Schreiben und Lesen manuell
positionieren müssen.
Evtl. kommst du auch mit low level-IO in deinem Programm
gut zurecht (vor allem, wenn es eh nur byteweise arbeitet).
Dann macht es vielleicht Sinn, darauf umzusteigen.
Also zum Öffnen open zu nehmen, read und write zum Lesen/Schreiben
und close zum Schließen.
Unter Windows heißen diese Funktionen _open, _read usw., glaube ich.
Das hat den Vorteil, daß du dir mit der Funktion dup einen
zusätzlichen file descriptor für eine geöffnete Datei holen kannst,
und davon kannst du einen zum Schreiben und einen zum Lesen nehmen.
Die sollten unabhängig voneinander verschiedene Dateipositionen
halten können.
Möglicherweise ist auch ein Umstieg auf C++ sinnvoll.
Bei den dortigen fstream gibt es pro Datei von vornherein
zwei Dateipositionen: eine zum Schreiben und eine zum Lesen.
Robert schrieb:> Und wie geht der Modus, bei dem ich Lesen/Schreiben kann und er soll ein> neues File erstellen, wenn File nicht vorhanden ist.
a+
Ggf. nach dem Öffnen positionieren, weil sonst am Ende geschrieben wird.
Robert schrieb:> Wir haben es so gelöst, dass es jedes ASCII-Zeichen von der txt-Datei> bitweise verschlüsselt. und zwar wird immer das LSB von einem Byte in> der Bilddatei entweder gelöscht oder gesetzt, je nachdem ob das Bit vom> ASCII-Zeichen gesetzt ist oder nicht.
Das ist keine Verschlüsselung, sondern Steganografie, das sind zwei
grundlegend verschiedene Dinge. In diesem Fall handelt es sich ausserdem
um ein recht leicht auch ohne Kenntnis des Algorithmus aufdeckbares
Verfahren.
> Mit fgetc lese ich das Byte aus und mit fputc speichere ich es ab.> Da aber ein Zeiger eine Stelle rechts schiebt, wenn er gebraucht wird,> habe ich einen 2ten gemahct, aber dieser schiebt sich auch nach rechts,> wenn ich den 1en benutze. Kann man das nicht ändern?
Selbe Datei zweimal öffnen, also nicht einfach nur den FILE-Pointer
kopieren. Aufgrund von Buffering wird aber ohne weitere Massnahmen nicht
unbedingt das herauskommen was du dir erhoffst.
Warum liest du nicht einfach einen kompletten Block (z.B. 1024 Byte),
verarbeitest den, und schreibst ihn wieder zurück (nach entsprechendem
fseek() natürlich)?
In der Praxis ist es bei derartigen Programmen aber sowieso meist
empfehlenswert, nicht die Input-Datei selbst zu verändern, sondern die
geänderten Daten in eine neue Datei zu speichern. Das führt zu weniger
Überraschungen beim Benutzer und reduziert das Potential für ungewollten
Datenverlust.
> Und wie geht der Modus, bei dem ich Lesen/Schreiben kann und er soll ein> neues File erstellen, wenn File nicht vorhanden ist.
Gibt es in ANSI-C nicht. "w+" würde die Dateilänge auf 0 setzen, wenn
die Datei schon existiert, während du mit "a+" zwar vordergründig
erstmal dein Ziel erreichst, aber dann nicht beliebig in die Datei
schreiben, sondern nur am Ende anhängen kannst. Um das gewünschte zu
erreichen hilft nur, die Datei erstmal "r+" zu öffnen, und sie bei einem
Fehler mit einem zweiten fopen()-Aufruf (dann mit "w+" als Modus)
erzeugen. Allerdings gibt es leider keinen Standard-Weg, eine nicht
vorhandene Datei von anderen möglichen Fehlern zu unterscheiden. Bei
Binärdateien wie deiner TIF-Datei ist natürlich noch jeweils ein "b" bei
den Modi zu ergänzen.
Je nach Betriebssystem gibt es natürlich andere Möglichkeiten, die sind
dann aber nicht unbedingt portabel.
Andreas
Andreas Ferber schrieb:> In der Praxis ist es bei derartigen Programmen aber sowieso meist> empfehlenswert, nicht die Input-Datei selbst zu verändern, sondern die> geänderten Daten in eine neue Datei zu speichern. Das führt zu weniger> Überraschungen beim Benutzer und reduziert das Potential für ungewollten> Datenverlust.
Kann das nur unterstreichen.
Der übliche Weg ist es, nicht die Originaldatei direkt zu manipulieren,
sondern eine neue zu beschreiben.
Das geht auch soweit, dass gute Programme beim Kommando "Save" (also
Abspeichern auf denselben Dateinamen) immer eine neue temporäre Datei
erzeugen, und erst dann wenn das alles gut gegangen ist, wird die
Originaldatei gelöscht und die Kopie auf den alten Dateinamen umbenannt.
Auf die Art ist garantiert, dass man immer eine intakte Datei zur
Verfügung hat, auf die man im Falle eines Falles zurückgreifen kann.
Karl heinz Buchegger schrieb:> Das geht auch soweit, dass gute Programme beim Kommando "Save" (also> Abspeichern auf denselben Dateinamen) immer eine neue temporäre Datei> erzeugen, und erst dann wenn das alles gut gegangen ist, wird die> Originaldatei gelöscht und die Kopie auf den alten Dateinamen> umbenannt.
Das Löschen lassen wirklich gute Programme weg, da das Umbenennen die
alte Datei überschreibt. Das hat den Vorteil, daß es dann eine atomare
Operation ist. Wenn sonst was zwischen dem Löschen und dem Umbenennen
passiert, ist zwar die temporäre Datei noch da, aber nicht unter dem
bekannten Dateinamen, sondern meist versteckt unter irgendeinem
temporären Namen, unter dem der normale Benutzer es nicht wiederfindet.
Vielen Dank für die Antworten
Das dies kaum eine Verschlüsselung ist, war mir klar. Es ist ja auch nur
ein Schulprojekt. :D
Andreas Ferber schrieb:> Selbe Datei zweimal öffnen, also nicht einfach nur den FILE-Pointer>> kopieren. Aufgrund von Buffering wird aber ohne weitere Massnahmen nicht>> unbedingt das herauskommen was du dir erhoffst.
Diselbe DAtei kann man nicht 2x mit fopen öffnen. Oder habe ich es
falsch verstanden?
Andreas Ferber schrieb:> Warum liest du nicht einfach einen kompletten Block (z.B. 1024 Byte),>> verarbeitest den, und schreibst ihn wieder zurück (nach entsprechendem>> fseek() natürlich)?
Meinst du, dies in einem Array speichern. Anschliessend bearbeiten und
dann wieder ins Array zurückkopieren und dann wieder in die tif-Datei
speichern?
Andreas Ferber schrieb:> In der Praxis ist es bei derartigen Programmen aber sowieso meist>> empfehlenswert, nicht die Input-Datei selbst zu verändern, sondern die>> geänderten Daten in eine neue Datei zu speichern. Das führt zu weniger>> Überraschungen beim Benutzer und reduziert das Potential für ungewollten>> Datenverlust.
Du meinst, ich soll eine Kopie von der tif-Datei erstellen, dass ich 1
txt-file und 2 tif-Files habe? Aus einer Bild-Datei lese ich die
Original Bytes aus und die 2te-Bild Datei wird die veränderten Bytes
abgespeichert, verchlüsselt?
Es tut mir Leid, dass ich vielleicht blöde Fragen stelle, aber ich bin
noch in der Ausbildung.
Robert schrieb:> Diselbe DAtei kann man nicht 2x mit fopen öffnen. Oder habe ich es> falsch verstanden?
Das düfte vom Betriesbssystem abhängen.
> Andreas Ferber schrieb:>> Warum liest du nicht einfach einen kompletten Block (z.B. 1024 Byte),>> verarbeitest den, und schreibst ihn wieder zurück (nach entsprechendem>> fseek() natürlich)?>> Meinst du, dies in einem Array speichern. Anschliessend bearbeiten und> dann wieder ins Array zurückkopieren und dann wieder in die tif-Datei> speichern?
Ungefähr so. Wobei ich zwei separate Arrays für Quelle und Ziel
verwenden würde.
> Du meinst, ich soll eine Kopie von der tif-Datei erstellen, dass ich 1> txt-file und 2 tif-Files habe?
Warum solltest du die tif-Datei erst kopieren, nur um die Kopie gleich
danach wieder zu überschrieben?
Du schreibst einfach deine Zieldaten in eine neue Datei.
Vielen Dank, ich habe jetzt eine weitere Version gemacht, mit der ich
nur mit dem Array arbeite. Es ist viel einfacher und übersichtlicher.
Ich habe noch eine weitere Frage:
Gibt es einen Modus, der vom Anfang vom File anfängt schreiben und auch
nicht das ganze File löscht?
lg
r+ Open for reading and writing. The stream is positioned
at the beginning of the file.
w+ Open for reading and writing. The file is created if
it does not exist, otherwise it is truncated.
The stream is positioned at the beginning of the file.