2 Übungen | |
→ | 2.8 Übung 7 |
Theorie |
Aufgabe 1: Binärdatei schreiben |
Aufgabe 2: Binärdatei lesen |
Machen Sie sich mit dem Lesen und Schreiben von Dateien vertraut, siehe Abschnitt Häufig auftretende Problemstellungen → Dateien lesen und schreiben → Gepufferte Ein-/Ausgabe.
/** @file ex064.c Beispielprogramm binaeres Schreiben.
*/
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include "he-read.h"
/** Name der zu schreibenden Datei.
*/
static const char filename[] = {
#ifdef _WIN32
"C:\\Temp\\ex064.dat"
#else
"ex064.dat"
#endif
};
/** Hauptprogramm.
@return 0 bei Erfolg.
*/
int
main(void)
{
FILE *outf = NULL; /* Ausgabedatei */
double *werte = NULL; /* Puffer fuer die Werte */
int exc = 1; /* Exit-Status */
int num = 0; /* Anzahl der Werte */
int i; /* Index fuer aktuell einzulesenden Wert */
/* Anzahl der Werte einlesen */
if (0 == hsm_et_read_int("Anzahl der Werte: ", &num)) {
goto finished;
}
/* Werte-Anzahl pruefen (positiv, aber kein Ueberlauf) */
if (1 > num) {
fputs("FEHLER: Die Werte-Anzahl muss mindestens 1 sein!\n", stderr);
fflush(stderr);
goto finished;
}
if ((SIZE_MAX / sizeof(double)) < (size_t)num) {
fputs("FEHLER: Zu viele Werte!\n", stderr);
fflush(stderr);
goto finished;
}
/* Speicher anfordern und Ergebnis pruefen */
werte = (double *)calloc( (size_t)num, sizeof(double) );
if (NULL == werte) {
fputs("FEHLER: Kein Speicher verfuegbar!\n", stderr);
fflush(stderr);
goto finished;
}
/* Werte einlesen */
for (i = 0; i < num; i++) {
printf("Bitte Wert %d eingeben: ", (i+1));
if (0 == hsm_et_read_double(NULL, &(werte[i]))) {
goto finished;
}
}
/* Datei oeffnen, binaeres Schreiben */
??? = fopen(???, ???);
if (NULL == outf) {
i = errno;
fprintf(stderr, "FEHLER: Datei \"%s\" nicht geoeffnet!\n", filename);
errno = i;
perror("fopen");
goto finished;
}
/* Anzahl der Datensaetze schreiben */
if(1 != fwrite(&num, sizeof(int), ???, outf)) {
i = errno;
fputs("FEHLER: Schreiben in Datei fehlgeschlagen!\n", stderr);
fflush(stderr);
errno = i;
perror("fwrite");
goto finished;
}
/* Daten schreiben */
if ((size_t)num != fwrite(werte, sizeof(???), ???, outf)) {
i = errno;
fputs("FEHLER: Schreiben in Datei fehlgeschlagen!\n", stderr);
fflush(stderr);
errno = i;
perror("fwrite");
goto finished;
}
/* Erfolg in Exit-Status vermerken */
exc = 0;
/* Aufraeumarbeiten und Programmende.
----------------------------------
*/
finished:
/* Ausgabedatei schliessen, falls erfolgreich geoeffnet.
*/
if (NULL != ???) {
if (0 != fclose(???)) {
exc = 1;
}
}
/* Dynamisch allozierten Speicher wieder freigeben, falls erhalten.
*/
if (NULL != werte) {
free(werte);
}
/* Programm beenden.
*/
exit(exc); return exc;
}
/* vim: set ai sw=4 ts=4 expandtab : */
Das Programm ex064 soll eine Reihe von double-Werten (Anzahl num) zunächst in den Hauptspeicher einlesen. Dafür muss zuvor dynamisch Speicher beschafft werden. Die eingelesenen Werte sollen dann binär in die Datei ex064.dat im Verzeichnis C:\Temp (Windows) bzw. im aktuellen Verzeichnis (Linux) geschrieben werden.
Datei-Aufbau: In die Datei wird zuerst der int-Wert
num geschrieben, dies ist die Anzahl der double-Werte.
Darauf folgen die double-Werte selbst.
Vervollständigen bzw. korrigieren Sie ex064.c, erstellen und testen Sie das Programm ex064.
/** @file ex065.c Beispielprogramm binaeres Lesen.
*/
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include "he-read.h"
/** Name der zu schreibenden Datei.
*/
static const char filename[] = {
#ifdef _WIN32
"C:\\Temp\\ex064.dat"
#else
"ex064.dat"
#endif
};
/** Hauptprogramm.
@return 0 bei Erfolg.
*/
int
main(void)
{
double *werte = NULL; /* Dynamischer Speicher fuer Werte */
??? *inpf = NULL; /* Eingabedatei */
int num = 0; /* Anzahl der double-Werte */
int exc = 1; /* Exit-Status-Code */
int i; /* Index, aktuell auszugebender Wert */
/* Eingabedatei zum binaeren Lesen oeffnen */
??? = fopen(???, ???);
if (NULL == inpf) {
fprintf(stderr, "FEHLER: Datei \"%s\" nicht geoeffnet!\n", filename);
fflush(stderr);
goto finished;
}
/* Anzahl der Datensaetze einlesen */
if (1 != fread(&num, sizeof(???), ???, inpf)) {
i = errno;
fputs("FEHLER: Anzahl der Datensaetze nicht gelesen!\n", stderr);
fflush(stderr);
errno = i;
perror("fread");
goto finished;
}
/* Eingelesene Anzahl pruefen (positiv, kein Ueberlauf) */
if (1 > num) {
fputs("FEHLER: Anzahl der Datensaetze muss mindestens 1 sein!\n",stderr);
fflush(stderr);
goto finished;
}
if((SIZE_MAX / sizeof(double)) < (size_t)num) {
fputs("FEHLER: Anzahl der Datensaetze zu gross!\n", stderr);
fflush(stderr);
goto finished;
}
/* Speicher dynamisch anfordern */
werte = (double *)calloc(sizeof(???), ???);
if (NULL == werte) {
fputs("FEHLER: Kein Speicher verfuegbar!\n", stderr);
fflush(stderr);
goto finished;
}
/* Werte einlesen */
if ((size_t)num != fread(werte, sizeof(???), (size_t)???, inpf)) {
i = errno;
fputs("FEHLER: Einlesen der Werte fehlgeschlagen!\n", stderr);
fflush(stderr);
errno = i;
perror("fread");
goto finished;
}
/* Erfolg vermerken */
exc = 0;
/* Werte ausgeben */
for (i = 0; i < num; i++) {
printf("Wert %d: %lg\n", (i+1), werte[i]);
}
/* Aufraeumarbeiten und Programmende.
----------------------------------
*/
finished:
/* Dynamisch allozierten Speicher fuer Werte freigeben, falls erhalten.
*/
if (NULL != werte) {
free(werte);
}
/* Eingabedatei schliessen, falls erfolgreich geoeffnet.
*/
if (NULL != inpf) {
fclose(inpf);
}
/* Programm verlassen, Exit-Status-Code zurueckgeben.
*/
exit(exc); return exc;
}
/* vim: set ai sw=4 ts=4 expandtab : */
Das Programm ex065 soll die vom Programm ex064 erzeugte Binärdatei wieder einlesen und anschließend die double-Werte ausgeben.
Vervollständigen bzw. korrigieren Sie ex065.c, erstellen und testen Sie das Programm ex065.