Forum: PC-Programmierung 2 Pointer für 1 File


von Robert (Gast)


Angehängte Dateien:

Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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.

von Andreas F. (aferber)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Robert (Gast)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

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.

von Robert (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

PS: Ggf. natürlich wieder mit einem b dazu

von Robert (Gast)


Angehängte Dateien:

Lesenswert?

Vielen Dank für die Antworten

Ich habs jetzt geschafft. Es funktioniert tatsächlich mit w+.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.