Dateizugriff, schreiben/lesen

Schnelle objektorientierte, kompilierende Programmiersprache.
DanB
Beiträge: 7
Registriert: Di Mär 29, 2016 10:24 am

Dateizugriff, schreiben/lesen

Beitrag von DanB » Di Mär 29, 2016 11:09 am

Hallo,
ich habe für nach den Osterferien eine Arbeit abzugeben, es geht um Datezugriffe und da sind einige Sachen die ich nicht so ganz verstanden habe, das wäre einmal bei:
- fread(const void *ptr, size_t size, size_t Count, FILE *stream): was sagt mir der dritte Parameter(size_t Count) ?
- fwrite(" "): die gleiche Frage ?
- was macht das b in fopen("Hallo.dat","ab") die Datei wir dann im Binärmodus geöffnet, was heisst das und welchen Nutzen habe ich davon ?

Hier nun der Code, ich muss eine Struktur einlesen und diese dann in einer Datei schreiben. Um Zahlen einzulesen und in die Datei zu schreiben, benutze ich fscanf(); und fprintf(); für die Strings benutze ich fgets(); und fputs(); das Problem ist ich würde gerne das nach jedem schreiben des Strings in die Datei, der Pointer an die neue Linie geht, was aber bei fscanf();/fprintf(); nicht der Fall ist sondern nur bei fgets();/fputs(); der Fall ist. Ich würde gerne mit fread(); und fwrite(); arbeiten aber da habe ich einen der Parameter nicht ganz verstanden. :cry:
-

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
struct reference
{
    long IdReference;
    char Nom[50];
    char Millesime[5];
    char Appellation[40];
    float DegreAlcool;
};
void encodage(struct reference *,FILE *);
int main ()
{
    FILE *pFile;
    pFile=fopen("Datei.dat","w");
    if(pFile==NULL)
        perror("");
    struct reference refe;
    encodage(&refe,pFile);
    fclose(pFile);
    return 0;
}
void encodage(struct reference *pv,FILE *pFile)
{
    fflush(stdin);
    printf("IdReference:");
    fscanf(stdin,"%ld",&pv->IdReference);
    fprintf(pFile,"%ld",pv->IdReference);
    
    fflush(stdin);
    printf("Nom:");
    fgets(pv->Nom,50,stdin);
    fputs(pv->Nom,pFile);
    
    fflush(stdin);
    printf("Millesime:");
    fgets(pv->Millesime,5,stdin);
    fputs(pv->Millesime,pFile);
    
    fflush(stdin);
    printf("Appellation:");
    fgets(pv->Appellation,40,stdin);
    fputs(pv->Appellation,pFile);
    
    fflush(stdin);
    printf("DegreAlcool:");
    fscanf(stdin,"%f",&pv->DegreAlcool);
    fprintf(pFile,"%f",pv->DegreAlcool);
}
Der Inhalt der Dateisieht anschliessend so aus:
1234Daniel
1995qwert
12.600000
wann geht der Pointer an die neue Linie ? :?: :?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Dateizugriff, schreiben/lesen

Beitrag von cloidnerux » Di Mär 29, 2016 11:29 am

Hi und Willkommen im Forum :D
fread(const void *ptr, size_t size, size_t Count, FILE *stream): was sagt mir der dritte Parameter(size_t Count) ?
- fwrite(" "): die gleiche Frage ?
https://www.proggen.org/doku.php?id=c:lib:stdio:fread
was macht das b in fopen("Hallo.dat","ab") die Datei wir dann im Binärmodus geöffnet, was heisst das und welchen Nutzen habe ich davon ?
Aus der cplusplus.com Seite zu fopen:
Text files are files containing sequences of lines of text. Depending on the environment where the application runs, some special character conversion may occur in input/output operations in text mode to adapt them to a system-specific text file format. Although on some environments no conversions occur and both text files and binary files are treated the same way, using the appropriate mode improves portability.
Bei einer Binärdatei werden die Daten so hinein geschrieben, wie du sie sendest. Möchtest du den Inhalt einer 4-Byt Variable speichern(int), so werden diese 4 byte auf die Festplatte geschrieben.
Öffnest du die Datei im Text Modus, so werden diese 4 Byte konvertiert zu einem Text, daher erhälst du statt der Binär-Darstellung eine Text Darstellung.
wann geht der Pointer an die neue Linie ?
Wrsl dadurch, dass du mit fscanf den Newline-Character('\n') aus der Konsole mit einliest, den der Nutzer Eintippt wenn er seine Eingabe mit Enter bestätigt.
Ein Zeilenumbruch existiert defakto nicht für den Computer, es ist eine reine Änderung der Anzeige. Um mitzuteilen, dass du jetzt einen Zeilenumbruch haben möchtest, schreibt man den Newline-Character Code ('\n').
Redundanz macht wiederholen unnötig.
quod erat expectandum

DanB
Beiträge: 7
Registriert: Di Mär 29, 2016 10:24 am

Re: Dateizugriff, schreiben/lesen

Beitrag von DanB » Di Mär 29, 2016 12:13 pm

Vielen Danke für die schnelle Antwort :D
OK, das heisst das wenn ich mit fscanf(); einen Wert einlese der den Newline caracter mitnimmt in die Datei, die Datei das aber nicht anzeigt also nicht an die neue Linie geht ?
Gibt es eine alternative zu fgets(); für integer damit der automatisch an die neue Linie geht ?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Dateizugriff, schreiben/lesen

Beitrag von Xin » Di Mär 29, 2016 1:55 pm

DanB hat geschrieben:Vielen Danke für die schnelle Antwort :D
OK, das heisst das wenn ich mit fscanf(); einen Wert einlese der den Newline caracter mitnimmt in die Datei, die Datei das aber nicht anzeigt also nicht an die neue Linie geht ?
Gibt es eine alternative zu fgets(); für integer damit der automatisch an die neue Linie geht ?
Falls ich das gerade richtig verstehe... Dir fehlt einfach ein Newline in der Datei?

Schreib doch einfach an passender Stelle eins hin. :)

Code: Alles auswählen

fputs( "\n", pFile );
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

DanB
Beiträge: 7
Registriert: Di Mär 29, 2016 10:24 am

Re: Dateizugriff, schreiben/lesen

Beitrag von DanB » Di Mär 29, 2016 3:36 pm

Ohhman vielen Dank, ich hab noch viel zu lernen was dieses Thema betrifft :)

DanB
Beiträge: 7
Registriert: Di Mär 29, 2016 10:24 am

Re: Dateizugriff, schreiben/lesen

Beitrag von DanB » Di Mär 29, 2016 3:54 pm

Hab noch eine kleine Frage, wenn ich die Datei komplett durchlaufen will und die Zahlen miteinander vergleichen will, dann geht der einfach aus der Schleife, wieso ?

Code: Alles auswählen

while(fscanf(pFile,"%ld",&a))
    {
        printf("%ld",&a);
        if(reference.IdReference==a)
            /*Mach irgendwas*/
    }

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Dateizugriff, schreiben/lesen

Beitrag von Xin » Di Mär 29, 2016 4:06 pm

Ähh.. ja - aber da ist ja noch was mehr - schließlich stehen die IdReferences ja nicht direkt hintereinander. Du musst ja auch den Rest von dem Datensatz noch überspringen, falls es die falsche Id ist.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

DanB
Beiträge: 7
Registriert: Di Mär 29, 2016 10:24 am

Re: Dateizugriff, schreiben/lesen

Beitrag von DanB » Di Mär 29, 2016 4:16 pm

Ja stimmt, aber wie finde ich die Anzahl Byte/Blöcke raus um mit fseek zur nächsten IdReference zu springen ?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Dateizugriff, schreiben/lesen

Beitrag von Xin » Di Mär 29, 2016 4:27 pm

Gar nicht, da Du keine festen Größen hast. Du musst jeden Eintrag komplett einlesen.
Das würde ich auch sofort tun: Initialisiere Deine "struct reference" und mach dann den Vergleich. Wenn sie passt, passt sie. Wenn nicht, hast Du alles überflüssige bereits ausgelesen und kannst den nächsten Datensatz lesen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Dateizugriff, schreiben/lesen

Beitrag von mfro » Di Mär 29, 2016 6:28 pm

Ich denke, Du hast das zwar grundsätzlich richtig gemacht, man hat aber möglicherweise etwas anderes von dir erwartet.

Du liest und schreibst deine Daten (die in der Struktur binär vorliegen) in ASCII. Das ist zwar grundsätzlich nicht verkehrt (weil der Inhalt der Datei dann nicht von der möglicherweise plattformabhängigen Darstellung im Speicher abhängt), ist aber möglicherweise gar nicht die Aufgabe.

M. E. solltest Du erst mal (anhand der Aufgabenstellung) klären, ob nicht die Binärdarstellung in der Datei gefragt ist. Dann würdest Du die Struktur als Ganzes binär wegschreiben und lesen und könntest (weil sie eine bekannte Größe hat) auch gezielt einzelne Datensätze (=Strukturinstanzen) in der Datei "anfahren".

P.S.: fflush(stdin) ist normalerweise keine gute Idee. Das funktioniert nur auf Windows (und auch da nur "aus Versehen") und entspricht keinem Standard. Auf allen anderen Plattformen fliegt man damit auf die Nase (der C-Standard definiert das als undefined behaviour).
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Antworten